CStringUtils.h
#pragma once
#include <string>
#include <vector>
#include <tchar.h>
#include <windows.h>
#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
// 字符串转换实用工具
namespace CStringUtils
{
// 查找字符串位置(忽略大小写)
size_t FindNoCaseA(const std::string& strMain, const std::string& strSub, size_t offset = 0);
size_t FindNoCaseW(const std::wstring& strMain, const std::wstring& strSub, size_t offset = 0);
size_t FindNoCase(const _tstring& strMain, const _tstring& strSub, size_t offset = 0);
// 替换字符串(忽略大小写)
std::string& ReplaceNoCaseA(std::string& strMain, const std::string& strSub, const std::string& strTarget);
std::wstring& ReplaceNoCaseW(std::wstring& strMain, const std::wstring& strSub, const std::wstring& strTarget);
_tstring& ReplaceNoCase(_tstring& strMain, const _tstring& strSub, const _tstring& strTarget);
// 替换字符串
std::string& ReplaceA(std::string& strSrc, const std::string& strFind, const std::string& strReplace, bool bCase = false);
std::wstring& ReplaceW(std::wstring& strSrc, const std::wstring& strFind, const std::wstring& strReplace, bool bCase = false);
_tstring& Replace(_tstring& strSrc, const _tstring& strFind, const _tstring& strReplace, bool bCase = false);
// 比较字符串
int CompareA(const std::string& strSrc, const std::string& strDest, bool bCase = true);
int CompareW(const std::wstring& strSrc, const std::wstring& strDest, bool bCase = true);
int Compare(const _tstring& strSrc, const _tstring& strDest, bool bCase = true);
// 分割字符串
std::vector<std::string> SplitStrA(const std::string& str, const std::string& delim);
std::vector<std::wstring> SplitStrW(const std::wstring& str, const std::wstring& delim);
std::vector<_tstring> SplitStr(const _tstring& str, const _tstring& delim);
// 格式化字符串
std::string FormatA(LPCSTR pFormat, ...);
std::wstring FormatW(LPCWSTR pFormat, ...);
_tstring Format(LPCTSTR pFormat, ...);
}
CStringUtils.cpp
#include "CStringUtils.h"
#include <tchar.h>
namespace CStringUtils
{
const int nStrFormatCountMax = (1024 * 1024 * 64);
size_t FindNoCaseA(const std::string& strMain, const std::string& strSub, size_t offset/* = 0*/)
{
size_t findPos = std::string::npos;
do
{
// 主串长度比字串小, 不需要比较
if (strMain.size() < strSub.size())
{
break;
}
std::string strMainTmp = strMain;
std::string strSubTmp = strSub;
// 转换大小写
for (auto& item : strMainTmp)
{
if (item >= _T('A') && item <= _T('Z')) item += 0x20;
}
for (auto& item : strSubTmp)
{
if (item >= _T('A') && item <= _T('Z')) item += 0x20;
}
findPos = strMainTmp.find(strSubTmp, offset);
} while (false);
return findPos;
}
size_t FindNoCaseW(const std::wstring& strMain, const std::wstring& strSub, size_t offset/* = 0*/)
{
size_t findPos = std::wstring::npos;
do
{
// 主串长度比字串小, 不需要比较
if (strMain.size() < strSub.size())
{
break;
}
std::wstring strMainTmp = strMain;
std::wstring strSubTmp = strSub;
// 转换大小写
for (auto& item : strMainTmp)
{
if (item >= _T('A') && item <= _T('Z')) item += 0x20;
}
for (auto& item : strSubTmp)
{
if (item >= _T('A') && item <= _T('Z')) item += 0x20;
}
findPos = strMainTmp.find(strSubTmp, offset);
} while (false);
return findPos;
}
size_t FindNoCase(const _tstring& strMain, const _tstring& strSub, size_t offset/* = 0*/)
{
#ifdef _UNICODE
return FindNoCaseW(strMain, strSub, offset);
#else
return FindNoCaseA(strMain, strSub, offset);
#endif
}
std::string& ReplaceNoCaseA(std::string& strMain, const std::string& strSub, const std::string& strTarget)
{
if (strSub.empty())
{
return strMain;
}
size_t nFind = 0;
while (_tstring::npos != (nFind = FindNoCaseA(strMain, strSub, nFind)))
{
strMain.replace(nFind, strSub.size(), strTarget);
nFind += strTarget.size();
};
return strMain;
}
std::wstring& ReplaceNoCaseW(std::wstring& strMain, const std::wstring& strSub, const std::wstring& strTarget)
{
if (strSub.empty())
{
return strMain;
}
size_t nFind = 0;
while (_tstring::npos != (nFind = FindNoCaseW(strMain, strSub, nFind)))
{
strMain.replace(nFind, strSub.size(), strTarget);
nFind += strTarget.size();
};
return strMain;
}
_tstring& ReplaceNoCase(_tstring& strMain, const _tstring& strSub, const _tstring& strTarget)
{
#ifdef _UNICODE
return ReplaceNoCaseW(strMain, strSub, strTarget);
#else
return ReplaceNoCaseA(strMain, strSub, strTarget);
#endif
}
std::string& ReplaceA(std::string& strMain, const std::string& strSub, const std::string& strTarget, bool bCase/* = false*/)
{
if (strSub.empty())
{
return strMain;
}
if (bCase)
{
size_t nFind = 0;
while (std::string::npos != (nFind = strMain.find(strSub, nFind)))
{
strMain.replace(nFind, strSub.size(), strTarget);
nFind += strTarget.size();
}
}
else
{
return ReplaceNoCaseA(strMain, strSub, strTarget);
}
return strMain;
}
std::wstring& ReplaceW(std::wstring& strMain, const std::wstring& strSub, const std::wstring& strTarget, bool bCase/* = false*/)
{
if (strSub.empty())
{
return strMain;
}
if (bCase)
{
size_t nFind = 0;
while (std::wstring::npos != (nFind = strMain.find(strSub, nFind)))
{
strMain.replace(nFind, strSub.size(), strTarget);
nFind += strTarget.size();
};
}
else
{
return ReplaceNoCaseW(strMain, strSub, strTarget);
}
return strMain;
}
_tstring& Replace(_tstring& strMain, const _tstring& strSub, const _tstring& strTarget, bool bCase/* = false*/)
{
#ifdef _UNICODE
return ReplaceW(strMain, strSub, strTarget, bCase);
#else
return ReplaceA(strMain, strSub, strTarget, bCase);
#endif
}
int CompareA(const std::string& strSrc, const std::string& strDest, bool bCase /* = true*/)
{
if (bCase)
{
return strcmp(strSrc.c_str(), strDest.c_str());
}
return _stricmp(strSrc.c_str(), strDest.c_str());
}
int CompareW(const std::wstring& strSrc, const std::wstring& strDest, bool bCase /* = true*/)
{
if (bCase)
{
return wcscmp(strSrc.c_str(), strDest.c_str());
}
return _wcsicmp(strSrc.c_str(), strDest.c_str());
}
int Compare(const _tstring& strSrc, const _tstring& strDest, bool bCase /* = true*/)
{
#ifdef _UNICODE
return CompareW(strSrc, strDest, bCase);
#else
return CompareA(strSrc, strDest, bCase);
#endif
}
std::vector<std::string> SplitStrA(const std::string& str, const std::string& delim)
{
std::vector<std::string> vectorOut;
size_t iStart = 0;
size_t iEnd = 0;
if (delim.empty())
{
vectorOut.push_back(str);
}
else
{
while ((iStart = str.find_first_not_of(delim, iEnd)) != std::string::npos)
{
iEnd = str.find(delim, iStart);
vectorOut.push_back(str.substr(iStart, iEnd - iStart));
}
}
return vectorOut;
}
std::vector<std::wstring> SplitStrW(const std::wstring& str, const std::wstring& delim)
{
std::vector<std::wstring> vectorOut;
size_t iStart = 0;
size_t iEnd = 0;
if (delim.empty())
{
vectorOut.push_back(str);
}
else
{
while ((iStart = str.find_first_not_of(delim, iEnd)) != std::wstring::npos)
{
iEnd = str.find(delim, iStart);
vectorOut.push_back(str.substr(iStart, iEnd - iStart));
}
}
return vectorOut;
}
std::vector<_tstring> SplitStr(const _tstring& str, const _tstring& delim)
{
#ifdef _UNICODE
return SplitStrW(str, delim);
#else
return SplitStrA(str, delim);
#endif
}
std::string FormatA(LPCSTR pFormat, ...)
{
size_t nCchCount = MAX_PATH;
std::string strResult(nCchCount, 0);
va_list args;
va_start(args, pFormat);
do
{
//成功则赋值字符串并终止循环
int nSize = _vsnprintf_s(&strResult[0], nCchCount, _TRUNCATE, pFormat, args);
if (-1 != nSize)
{
strResult.resize(nSize);
break;
}
//缓冲大小超限终止
if (nCchCount >= nStrFormatCountMax)
{
break;
}
//重新分配缓冲
nCchCount *= 2;
strResult.resize(nCchCount);
} while (true);
va_end(args);
return strResult;
}
std::wstring FormatW(LPCWSTR pFormat, ...)
{
size_t nCchCount = MAX_PATH;
std::wstring strResult(nCchCount, 0);
va_list args;
va_start(args, pFormat);
do
{
//格式化输出字符串
int nSize = _vsnwprintf_s(&strResult[0], nCchCount, _TRUNCATE, pFormat, args);
if (-1 != nSize)
{
strResult.resize(nSize);
break;
}
//缓冲大小超限终止
if (nCchCount >= nStrFormatCountMax)
{
break;
}
//重新分配缓冲
nCchCount *= 2;
strResult.resize(nCchCount);
} while (true);
va_end(args);
return strResult;
}
_tstring Format(LPCTSTR pFormat, ...)
{
size_t nCchCount = MAX_PATH;
_tstring strResult(nCchCount, 0);
va_list args;
va_start(args, pFormat);
do
{
//格式化输出字符串
int nSize = _vsntprintf_s(&strResult[0], nCchCount, _TRUNCATE, pFormat, args);
if (-1 != nSize)
{
strResult.resize(nSize);
break;
}
//缓冲大小超限终止
if (nCchCount >= nStrFormatCountMax)
{
break;
}
//重新分配缓冲
nCchCount *= 2;
strResult.resize(nCchCount);
} while (true);
va_end(args);
return strResult;
}
}
main.cpp
#include <iostream>
#include "CStringUtils.h"
int main()
{
_tstring strSrc = _T("FlameCyclone");
strSrc = CStringUtils::Replace(strSrc, _T("Lone"), _T("23424"), false);
return 0;
}