c_cpp StringsAPI用于STL字符串

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp StringsAPI用于STL字符串相关的知识,希望对你有一定的参考价值。

#pragma once

/*
    Depends on:
    - string
    - vector (optional)
    - set (optional)
    - winternl.h (optional)
*/

namespace StringsAPI {

#ifdef _WINTERNL_
    std::string AnsiStringToString(PCANSI_STRING AnsiString);
    std::wstring UnicodeStringToString(PCUNICODE_STRING UnicodeString);
#endif

    std::string LowerCase(__in std::string String);
    std::wstring LowerCase(__in std::wstring String);
    void LowerCaseRef(__inout std::string& String);
    void LowerCaseRef(__inout std::wstring& String);

    std::string UpperCase(__in std::string String);
    std::wstring UpperCase(__in std::wstring String);
    void UpperCaseRef(__inout std::string& String);
    void UpperCaseRef(__inout std::wstring& String);

    bool StartsWith(const std::string& String, const std::string& Beginning);
    bool StartsWith(const std::wstring& String, const std::wstring& Beginning);

    bool EndsWith(const std::string& String, const std::string& Ending);
    bool EndsWith(const std::wstring& String, const std::wstring& Ending);

    std::string FillLeft(const std::string& String, unsigned char Length, char Filler);
    std::wstring FillLeft(const std::wstring& String, unsigned char Length, wchar_t Filler);
    std::string FillRight(const std::string& String, unsigned char Length, char Filler);
    std::wstring FillRight(const std::wstring& String, unsigned char Length, wchar_t Filler);

    std::wstring AnsiToWide(const std::string& Wide);
    std::string WideToAnsi(const std::wstring& Ansi);

    std::string IntToAnsi(int Value, int Radix = 10);
    std::string Int64ToAnsi(long long Value, int Radix = 10);
    std::string UInt64ToAnsi(unsigned long long Value, int Radix = 10);
    std::wstring IntToWide(int Value, int Radix = 10);
    std::wstring Int64ToWide(long long Value, int Radix = 10);
    std::wstring UInt64ToWide(unsigned long long Value, int Radix = 10);

    inline std::string IntToAnsiHex(int Value) { return IntToAnsi(Value, 16); }
    inline std::string Int64ToAnsiHex(__int64 Value) { return Int64ToAnsi(Value, 16); }
    inline std::string UInt64ToAnsiHex(unsigned __int64 Value) { return UInt64ToAnsi(Value, 16); }
    inline std::wstring IntToWideHex(int Value) { return IntToWide(Value, 16); }
    inline std::wstring Int64ToWideHex(__int64 Value) { return Int64ToWide(Value, 16); }
    inline std::wstring UInt64ToWideHex(unsigned __int64 Value) { return UInt64ToWide(Value, 16); }

    inline std::string IntToAnsiBin(int Value) { return IntToAnsi(Value, 2); }
    inline std::string Int64ToAnsiBin(__int64 Value) { return Int64ToAnsi(Value, 2); }
    inline std::string UInt64ToAnsiBin(unsigned __int64 Value) { return UInt64ToAnsi(Value, 2); }
    inline std::wstring IntToWideBin(int Value) { return IntToWide(Value, 2); }
    inline std::wstring Int64ToWideBin(__int64 Value) { return Int64ToWide(Value, 2); }
    inline std::wstring UInt64ToWideBin(unsigned __int64 Value) { return UInt64ToWide(Value, 2); }

    template <typename T>
    inline std::string ValToAnsi(T Value) { return std::to_string(Value); }

    template <typename T>
    inline std::wstring ValToWide(T Value) { return std::to_wstring(Value); }

    template <typename T>
    inline int StrToInt(const T& Str) { return std::stoi(Str, nullptr, 0); }

    template <typename T>
    inline int StrToUInt(const T& Str) { return std::stoul(Str, nullptr, 0); }

    template <typename T>
    inline __int64 StrToInt64(const T& Str) { return std::stoll(Str, nullptr, 0); }

    template <typename T>
    inline unsigned __int64 StrToUInt64(const T& Str) { return std::stoull(Str, nullptr, 0); }

    template <typename T>
    inline int HexToInt(const T& Str) { return std::stoi(Str, nullptr, 16); }

    template <typename T>
    inline unsigned int HexToUInt(const T& Str) { return std::stoul(Str, nullptr, 16); }

    template <typename T>
    inline __int64 HexToInt64(const T& Str) { return std::stoll(Str, nullptr, 16); }

    template <typename T>
    inline unsigned __int64 HexToUInt64(const T& Str) { return std::stoull(Str, nullptr, 16); }

    template <typename T>
    inline int BinToInt(const T& Str) { return std::stoi(Str, nullptr, 2); }

    template <typename T>
    inline unsigned int BinToUInt(const T& Str) { return std::stoul(Str, nullptr, 2); }

    template <typename T>
    inline __int64 BinToInt64(const T& Str) { return std::stoll(Str, nullptr, 2); }

    template <typename T>
    inline unsigned __int64 BinToUInt64(const T& Str) { return std::stoull(Str, nullptr, 2); }

    template <typename T>
    inline float StrToFloat(const T& Str) { return std::stof(Str, nullptr); }

    template <typename T>
    inline double StrToDouble(const T& Str) { return std::stod(Str, nullptr); }

    std::string PtrToAnsi(const void* Ptr);
    std::wstring PtrToWide(const void* Ptr);

    template <typename T>
    T TrimLeft(const T& Str) {
        if (Str.empty()) return T();
        for (size_t i = 0; i < Str.length(); ++i) {
            decltype(T::value_type) c = Str[i];
            if (c != static_cast<decltype(T::value_type)>(' ') && c != static_cast<decltype(T::value_type)>('\t'))
                return Str.substr(i);
        }
        return T();
    }

    template <typename T>
    T TrimRight(const T& Str) {
        if (Str.empty()) return T();
        for (size_t i = Str.length() - 1; i >= 0; --i) {
            decltype(T::value_type) c = Str[i];
            if (c != static_cast<decltype(T::value_type)>(' ') && c != static_cast<decltype(T::value_type)>('\t'))
                return Str.substr(0, i + 1);
        }
        return T();
    }

    template <typename T>
    T Trim(const T& Str) {
        return TrimRight(TrimLeft(Str));
    }

    template <typename T>
    bool IsStrMatches(const T* Str, const T* Mask) {
        /*
            Dr.Dobb's Algorithm:
            http://www.drdobbs.com/architecture-and-design/matching-wildcards-an-empirical-way-to-t/240169123?queryText=path%2Bmatches
        */

        const T* TameText = Str;
        const T* WildText = Mask;
        const T* TameBookmark = static_cast<T*>(0x00);
        const T* WildBookmark = static_cast<T*>(0x00);

        while (true) {
            if (*WildText == static_cast<T>('*')) {
                while (*(++WildText) == static_cast<T>('*')); // "xy" matches "x**y"
                if (!*WildText) return true; // "x" matches "*"

                if (*WildText != static_cast<T>('?')) {
                    while (*TameText != *WildText) {
                        if (!(*(++TameText)))
                            return false;  // "x" doesn't match "*y*"
                    }
                }

                WildBookmark = WildText;
                TameBookmark = TameText;
            }
            else if (*TameText != *WildText && *WildText != static_cast<T>('?')) {
                if (WildBookmark) {
                    if (WildText != WildBookmark) {
                        WildText = WildBookmark;

                        if (*TameText != *WildText) {
                            TameText = ++TameBookmark;
                            continue; // "xy" matches "*y"
                        }
                        else {
                            WildText++;
                        }
                    }

                    if (*TameText) {
                        TameText++;
                        continue; // "mississippi" matches "*sip*"
                    }
                }

                return false; // "xy" doesn't match "x"
            }

            TameText++;
            WildText++;

            if (!*TameText) {
                while (*WildText == static_cast<T>('*')) WildText++; // "x" matches "x*"

                if (!*WildText) return true; // "x" matches "x"
                return false; // "x" doesn't match "xy"
            }
        }
    }

    // SimpleReplaceString("a ab abc", "a", "abc") -> "abc abcb abcbc"
    template <typename T>
    unsigned int SimpleReplaceString(__inout T& Text, const T& Source, const T& Destination) {
        size_t SourceLength = Source.length();
        size_t DestinationLength = Destination.length();
        unsigned int ReplacingsCount = 0;

        for (size_t Index = 0; Index = Text.find(Source, Index), Index != T::npos;) {
            Text.replace(Index, SourceLength, Destination);
            Index += DestinationLength;
            ++ReplacingsCount;
        }

        return ReplacingsCount;
    }

    // SelectiveReplaceString("a ab abc", "a", "abc") -> "abc abcb abc"
    template <typename T>
    unsigned int SelectiveReplaceString(__inout T& Text, const T& Source, const T& Destination) {
        size_t TextLength = Text.length();
        size_t SourceLength = Source.length();
        size_t DestinationLength = Destination.length();
        unsigned int ReplacingsCount = 0;

        T Environment(DestinationLength, NULL);
        decltype(T::value_type)* EnvironmentPtr = &Environment[0];

        for (size_t Index = 0; Index = Text.find(Source, Index), Index != T::npos;) {
            if (DestinationLength <= TextLength - Index) {
                memcpy(EnvironmentPtr, &Text[Index], DestinationLength * sizeof(decltype(T::value_type)));

                if (Environment == Destination) {
                    Index += DestinationLength;
                    continue;
                }
            }
            Text.replace(Index, SourceLength, Destination);
            Index += DestinationLength;
            TextLength = Text.length();
            ++ReplacingsCount;
        }

        return ReplacingsCount;
    };

    template <typename T>
    T ReplaceString(const T& Text, const T& Source, const T& Destination, bool Selective = false) {
        T Result(Text);
        if (Selective)
            SelectiveReplaceString(Result, Source, Destination);
        else
            SimpleReplaceString(Result, Source, Destination);
        return Result;
    }

    template <typename T>
    T FixWin32PathSlashes(const T& String) {
        static const decltype(T::value_type) ForwardSlash[] = { '/', NULL };
        static const decltype(T::value_type) BackwardSlash[] = { '\\', NULL };
        static const decltype(T::value_type) DoubleBackwardSlashes[] = { '\\', '\\', NULL };

        T Result(String);

        SimpleReplaceString(Result, T(ForwardSlash), T(BackwardSlash));
        while (SimpleReplaceString(Result, T(DoubleBackwardSlashes), T(BackwardSlash)));
        return Result;
    }

    template <typename T>
    T FixUnixPathSlashes(const T& String) {
        static const decltype(T::value_type) ForwardSlash[] = { '/', NULL };
        static const decltype(T::value_type) BackwardSlash[] = { '\\', NULL };
        static const decltype(T::value_type) DoubleForwardSlashes[] = { '/', '/', NULL };

        T Result(String);

        SimpleReplaceString(Result, T(BackwardSlash), T(ForwardSlash));
        while (SimpleReplaceString(Result, T(DoubleForwardSlashes), T(ForwardSlash)));
        return Result;
    }

    template <typename T>
    T FixUrlSlashes(const T& String) {
        static const decltype(T::value_type) ForwardSlash[] = { '/', NULL };
        static const decltype(T::value_type) BackwardSlash[] = { '\\', NULL };
        static const decltype(T::value_type) DoubleForwardSlashes[] = { '/', '/', NULL };
        static const decltype(T::value_type) UrlBrokenSlashes[] = { ':', '/', NULL };
        static const decltype(T::value_type) UrlBaseSlashes[] = { ':', '/', '/', NULL };

        T Result(String);

        SimpleReplaceString(Result, T(BackwardSlash), T(ForwardSlash));
        while (SimpleReplaceString(Result, T(DoubleForwardSlashes), T(ForwardSlash)));
        SimpleReplaceString(Result, T(UrlBrokenSlashes), T(UrlBaseSlashes));
        return Result;
    }

#ifdef _VECTOR_
    template <typename T>
    size_t Tokenize(const T& Str, const T& Delimiters, __out std::vector<T>& Tokens) {
        Tokens.clear();

        size_t Start = Str.find_first_not_of(Delimiters);
        size_t End = Start;

        while (Start != T::npos) {
            End = Str.find(Delimiters, Start);
            Tokens.emplace_back(Str.substr(Start, End - Start));
            Start = Str.find_first_not_of(Delimiters, End);
        }
        return Tokens.size();
    }

    template <typename T>
    size_t Split(const T& Str, const T& Delimiter, __out std::vector<T>& Tokens) {
        Tokens.clear();

        size_t Start = 0;
        size_t End = Str.find(Delimiter);
        size_t DelimLength = Delimiter.length();

        while (End != T::npos) {
            Tokens.emplace_back(Str.substr(Start, End - Start));
            Start = End + DelimLength;
            End = Str.find(Delimiter, Start);
        }

        Tokens.emplace_back(Str.substr(Start));
        return Tokens.size();
    }
#endif

#ifdef _SET_
    template <typename T>
    size_t Tokenize(const T& Str, const T& Delimiters, __out std::vector<T>& Tokens) {
        Tokens.clear();

        size_t Start = Str.find_first_not_of(Delimiters);
        size_t End = Start;

        while (Start != T::npos) {
            End = Str.find(Delimiters, Start);
            Tokens.emplace(Str.substr(Start, End - Start));
            Start = Str.find_first_not_of(Delimiters, End);
        }
        return Tokens.size();
    }

    template <typename T>
    size_t Split(const T& Str, const T& Delimiter, __out std::set<T>& Tokens) {
        Tokens.clear();

        size_t Start = 0;
        size_t End = Str.find(Delimiter);
        size_t DelimLength = Delimiter.length();

        while (End != T::npos) {
            Tokens.emplace(Str.substr(Start, End - Start));
            Start = End + DelimLength;
            End = Str.find(Delimiter, Start);
        }

        Tokens.emplace(Str.substr(Start));
        return Tokens.size();
    }
#endif

}
#define WIN32_LEAN_AND_MEAN

#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS

#include <string>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <set>

#include <winternl.h>

namespace StringsAPI {

    std::string AnsiStringToString(PCANSI_STRING AnsiString) {
        if (!AnsiString
            || !AnsiString->Buffer
            || !AnsiString->Length
            || !AnsiString->MaximumLength
            || AnsiString->MaximumLength < AnsiString->Length
            ) return std::string();

        return std::string(AnsiString->Buffer, AnsiString->Length);
    }

    std::wstring UnicodeStringToString(PCUNICODE_STRING UnicodeString) {
        if (!UnicodeString
            || !UnicodeString->Buffer
            || !UnicodeString->Length
            || !UnicodeString->MaximumLength
            || UnicodeString->MaximumLength < UnicodeString->Length
            ) return std::wstring();

        return std::wstring(UnicodeString->Buffer, UnicodeString->Length);
    }

    std::string LowerCase(std::string String) {
        std::transform(String.cbegin(), String.cend(), String.begin(), ::tolower);
        return String;
    }

    std::wstring LowerCase(std::wstring String) {
        std::transform(String.cbegin(), String.cend(), String.begin(), ::tolower);
        return String;
    }

    void LowerCaseRef(std::string& String) {
        std::transform(String.cbegin(), String.cend(), String.begin(), ::tolower);
    }

    void LowerCaseRef(std::wstring& String) {
        std::transform(String.cbegin(), String.cend(), String.begin(), ::tolower);
    }

    std::string UpperCase(std::string String) {
        std::transform(String.cbegin(), String.cend(), String.begin(), ::toupper);
        return String;
    }

    std::wstring UpperCase(std::wstring String) {
        std::transform(String.cbegin(), String.cend(), String.begin(), ::toupper);
        return String;
    }

    void UpperCaseRef(std::string& String) {
        std::transform(String.cbegin(), String.cend(), String.begin(), ::toupper);
    }

    void UpperCaseRef(std::wstring& String) {
        std::transform(String.cbegin(), String.cend(), String.begin(), ::toupper);
    }

    bool StartsWith(const std::string& String, const std::string& Beginning) {
        return (Beginning.size() <= String.size()) && std::equal(Beginning.begin(), Beginning.end(), String.begin());
    }

    bool StartsWith(const std::wstring& String, const std::wstring& Beginning) {
        return (Beginning.size() <= String.size()) && std::equal(Beginning.begin(), Beginning.end(), String.begin());
    }

    bool EndsWith(const std::string& String, const std::string& Ending) {
        return (Ending.size() <= String.size()) && std::equal(Ending.rbegin(), Ending.rend(), String.rbegin());
    }

    bool EndsWith(const std::wstring& String, const std::wstring& Ending) {
        return (Ending.size() <= String.size()) && std::equal(Ending.rbegin(), Ending.rend(), String.rbegin());
    }

    std::string FillLeft(const std::string& String, unsigned char Length, char Filler) {
        std::ostringstream OutputStringStream;
        OutputStringStream << std::right << std::setfill(Filler) << std::setw(Length) << String;
        return std::string(OutputStringStream.str());
    }

    std::wstring FillLeft(const std::wstring& String, unsigned char Length, wchar_t Filler) {
        std::wostringstream OutputStringStream;
        OutputStringStream << std::right << std::setfill(Filler) << std::setw(Length) << String;
        return OutputStringStream.str();
    }

    std::string FillRight(const std::string& String, unsigned char Length, char Filler) {
        std::ostringstream OutputStringStream;
        OutputStringStream << std::left << std::setfill(Filler) << std::setw(Length) << String;
        return OutputStringStream.str();
    }

    std::wstring FillRight(const std::wstring& String, unsigned char Length, wchar_t Filler) {
        std::wostringstream OutputStringStream;
        OutputStringStream << std::left << std::setfill(Filler) << std::setw(Length) << String;
        return OutputStringStream.str();
    }

    std::wstring AnsiToWide(const std::string& Ansi) {
        if (Ansi.empty()) return std::wstring();
        int BufferSize = MultiByteToWideChar(
            CP_ACP,
            MB_PRECOMPOSED,
            Ansi.c_str(),
            -1,
            NULL,
            0
        );
        if (BufferSize < 2) return std::wstring();
        std::wstring Wide(BufferSize, NULL);
        BufferSize = MultiByteToWideChar(
            CP_ACP,
            MB_PRECOMPOSED,
            Ansi.c_str(),
            -1,
            &Wide[0],
            BufferSize
        );
        if (BufferSize < 2) return std::wstring();
        Wide.resize(static_cast<size_t>(BufferSize) - 1);
        return Wide;
    }

    std::string WideToAnsi(const std::wstring& Wide) {
        if (Wide.empty()) return std::string();
        int BufferSize = WideCharToMultiByte(
            CP_ACP,
            WC_COMPOSITECHECK | WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR,
            Wide.c_str(),
            -1,
            NULL,
            0,
            NULL,
            NULL
        );
        if (BufferSize < 2) return std::string();
        std::string Ansi(BufferSize, NULL);
        BufferSize = WideCharToMultiByte(
            CP_ACP,
            WC_COMPOSITECHECK | WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR,
            Wide.c_str(),
            -1,
            &Ansi[0],
            BufferSize,
            NULL,
            NULL
        );
        if (BufferSize < 2) return std::string();
        Ansi.resize(static_cast<size_t>(BufferSize) - 1);
        return Ansi;
    }

    std::string IntToAnsi(int Value, int Radix) {
        char Buf[34];
        Buf[0] = 0x00;
        _itoa_s(Value, Buf, sizeof(Buf), Radix);
        return Buf;
    }

    std::string Int64ToAnsi(long long Value, int Radix) {
        char Buf[66];
        Buf[0] = 0x00;
        _i64toa_s(Value, Buf, sizeof(Buf), Radix);
        return Buf;
    }

    std::string UInt64ToAnsi(unsigned long long Value, int Radix) {
        char Buf[66];
        Buf[0] = 0x00;
        _ui64toa_s(Value, Buf, sizeof(Buf), Radix);
        return Buf;
    }

    std::wstring IntToWide(int Value, int Radix) {
        wchar_t Buf[34];
        Buf[0] = 0x00;
        _itow_s(Value, Buf, sizeof(Buf) / sizeof(*Buf), Radix);
        return Buf;
    }

    std::wstring Int64ToWide(long long Value, int Radix) {
        wchar_t Buf[66];
        Buf[0] = 0x00;
        _i64tow_s(Value, Buf, sizeof(Buf) / sizeof(*Buf), Radix);
        return Buf;
    }

    std::wstring UInt64ToWide(unsigned long long Value, int Radix) {
        wchar_t Buf[66];
        Buf[0] = 0x00;
        _ui64tow_s(Value, Buf, sizeof(Buf) / sizeof(*Buf), Radix);
        return Buf;
    }

    std::string PtrToAnsi(const void* Ptr) {
#ifdef _AMD64_
        return UInt64ToAnsi(reinterpret_cast<unsigned long long>(Ptr), 16);
#else
        return IntToAnsi(reinterpret_cast<int>(Ptr), 16);
#endif
    }

    std::wstring PtrToWide(const void* Ptr) {
#ifdef _AMD64_
        return UInt64ToWide(reinterpret_cast<unsigned long long>(Ptr), 16);
#else
        return IntToWide(reinterpret_cast<int>(Ptr), 16);
#endif
    }

}

以上是关于c_cpp StringsAPI用于STL字符串的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp STL中的排序用法

c_cpp STL_sort_rank

c_cpp 用于检查输入是整数还是字符串的程序

c_cpp 用于生成十六进制字符串表示的NSData类别

c_cpp 用于cpp字符串的UTF8解码器类

如何使 c++ 代码既可用于 Qt 项目(QTL 风格)也可用于 C++ 项目(STL 风格)