c/c++日常工作开发中没有什么比字符串操作、文件操作用的更多了,这里记录一下工程里经常用到的字符串操作的一些代码片段,方便后面需要的朋友摘取使用:
1. 对std::string 首尾进行空格删除操作:
std::string StringStrim(_In_ std::string& strIn)
{
if (!strIn.empty())
{
strIn.erase(0, strIn.find_first_not_of(" "));
strIn.erase(strIn.find_last_not_of(" ") + 1);
}
return std::move(strIn);
}
2. 按照给定的特征对std::string 进行分割,并返回std::vector存储的分割后的内容:
std::vector<std::string> vStringSplit(_In_ const std::string& s, _In_ const std::string& delim)
{
std::vector<std::string> elems;
size_t pos = 0;
size_t len = s.length();
size_t delim_len = delim.length();
if (delim_len == 0)
return elems;
while (pos < len)
{
int find_pos = s.find(delim, pos);
if (find_pos < 0)
{
elems.push_back(s.substr(pos, len - pos));
break;
}
std::string sss(s.substr(pos, find_pos - pos));
if (sss.length() > 0 && sss != " ")
{
elems.push_back(sss);
}
pos = find_pos + delim_len;
}
return std::move(elems);
}
3. 对字符串进行URL格式编码或者反编码:
//需要使用的工具函数
unsigned char ToHex(unsigned char x)
{
return x > 9 ? x + 55 : x + 48;
}
unsigned char FromHex(unsigned char x)
{
unsigned char y;
if (x >= 'A' && x <= 'Z') y = x - 'A' + 10;
else if (x >= 'a' && x <= 'z') y = x - 'a' + 10;
else if (x >= '0' && x <= '9') y = x - '0';
return y;
}
static inline bool is_unambiguous(char c) {
return IS_ALPHANUM(c) ||
c == '-' ||
c == '_' ||
c == '.' ||
c == '/' ||
c == '~';
}
static inline unsigned char hex2i(char hex) {
return hex <= '9' ? hex - '0' :
hex <= 'F' ? hex - 'A' + 10 : hex - 'a' + 10;
}
//对std::string 进行URL编码
std::string url_escape(_In_ const char* istr)
{
std::string ostr;
const char* p = istr;
char szHex[4] = { 0 };
while (*p != '\0') {
if (is_unambiguous(*p)) {
ostr += *p;
}
else {
sprintf_s(szHex,4, "%%%02X", *p);
ostr += szHex;
}
++p;
}
return std::move(ostr);
}
//对URL类型字符串进行反编码
std::string url_unescape(_In_ const char* istr)
{
std::string ostr;
const char* p = istr;
while (*p != '\0') {
if (*p == '%' &&
IS_HEX(p[1]) &&
IS_HEX(p[2])) {
ostr += ((hex2i(p[1]) << 4) | hex2i(p[2]));
p += 3;
}
else {
ostr += *p;
++p;
}
}
return std::move(ostr);;
}
4. UNICODE/ANSI相关的转换
#define MAX_STRING_LENGTH 1024*1024
//代码里使用了std::make_shared,注意编译时的c++标准需要切换到17及其以上
bool Ansi_To_Unicode(_In_ const std::string& strIn, _Out_ std::wstring& strOut)
{
bool bCov = false;
size_t len = strIn.length();
if (len && len<= MAX_STRING_LENGTH)
{
int unicodeLen = MultiByteToWideChar(CP_ACP,
0,
strIn.c_str(),
-1,
NULL,
0);
auto pUnicode = std::make_shared<wchar_t[]>(unicodeLen + 1);
if(pUnicode)
{
MultiByteToWideChar(CP_ACP,
0,
strIn.c_str(),
-1,
(LPWSTR)pUnicode.get(),
unicodeLen);
strOut = pUnicode.get();
bCov = true;
}
else
{
//内存申请失败,大小为 unicodeLen
}
}
else
{
//字符串长度为0,或者长度大于1M
}
return bCov;
}
bool Unicode_To_Ansi(const std::wstring& strIn, std::string& strOut)
{
bool bCov = false;
int iLen = strIn.length() * 2;
if (iLen && iLen <= MAX_STRING_LENGTH)
{
auto pBuf = std::make_shared<char[]>(iLen + 1);
size_t iRet = WideCharToMultiByte(CP_ACP, 0, strIn.c_str(), -1, pBuf.get(), iLen, NULL, NULL);
if (iRet > 0)
{
strOut = pBuf.get();
bCov = true;
}
else
{
//字符串转换失败
}
}
else
{
//字符串长度为0,或者长度大于1M
}
return bCov;
}
bool string_To_UTF8(_In_ const std::string& str, _Out_ std::string& strOut)
{
bool bSuc = false;
int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
if (nwLen && nwLen<= MAX_STRING_LENGTH)
{
auto pwBuf = std::make_shared<wchar_t[]>(nwLen + 1);
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), (LPWSTR)pwBuf.get(), nwLen);
int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf.get(), -1, NULL, NULL, NULL, NULL);
if(nLen)
{
auto pBuf = std::make_shared<char[]>(nLen + 1);
::WideCharToMultiByte(CP_UTF8, 0, pwBuf.get(), nwLen, (LPSTR)pBuf.get(), nLen, NULL, NULL);
strOut = (char*)pBuf.get();
bSuc = true;
}
else
{
//内存申请失败
}
}
else
{
//字符串长度为0,或者长度大于1M
}
return bSuc;
}
bool UTF8_To_ANSI(_In_ std::string& strUtf8In,_Out_ std::string& strOut)
{
bool bSuc = false;
int nLen = MultiByteToWideChar(CP_UTF8, NULL, strUtf8In.c_str(), -1, NULL, NULL);
if (nLen && nLen <= MAX_STRING_LENGTH)
{
auto wszBuffer = std::make_shared<wchar_t[]>(nLen + 1);
nLen = MultiByteToWideChar(CP_UTF8, NULL, strUtf8In.c_str(), -1, wszBuffer.get(), nLen);
if (nLen)
{
wszBuffer[nLen] = 0;
nLen = WideCharToMultiByte(936, NULL, wszBuffer.get(), -1, NULL, NULL, NULL, NULL);
if (nLen)
{
auto szBuffer = std::make_shared<char[]>(nLen + 1);
nLen = WideCharToMultiByte(936, NULL, wszBuffer.get(), -1, (LPSTR)szBuffer.get(), nLen, NULL, NULL);
szBuffer[nLen] = 0;
strOut = (char*) szBuffer.get();
bSuc = true;
}
else
{
//内存申请失败
}
}
else
{
//内存申请失败
}
}
else
{
//字符串长度为0,或者长度大于1M
}
return bSuc;
}
5. GUID子串创建
//注意需要包含这个库
#pragma comment(lib,"rpcrt4.lib")
std::string MakeGuid()
{
std::string strGuid;
GUID guid;
if (S_OK == ::UuidCreate(&guid))
{
char cguid[128] = { 0 };
sprintf_s(cguid,128,"%08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
strGuid = cguid;
}
return strGuid;
}