先上效果图,代码在最后
int StrUtil::Split(const char* str, const char* div, char* pStrs[])
{
if (!div || !div[0]) { return -1; }
// 计算所需最小内存
auto getBytes = [&](int* pnStrs)->int {
*pnStrs = 0;
int nBytes = 0;
char* p0 = (char*)str;
for (char* p1 = strstr(p0, div); p1; p1 = strstr(p1 + 1, div))
{
++(*pnStrs);
nBytes += (p1 - p0);
nBytes += sizeof(char*);
p0 = p1;
}
nBytes += strlen(p0) + 1 + sizeof(char*);
++(*pnStrs);
return nBytes;
};
int nStrs = 0;
int nBytes = getBytes(&nStrs);
if (!pStrs) { return nBytes; }
// 函数要求pStrs必须满足大于等于nBytes,否则以下逻辑将导致内存溢出
char* pBytes = (char*)pStrs;
memset(pBytes, 0, nBytes);
pStrs[0] = pBytes + nStrs * sizeof(char*);
strcpy(pStrs[0], str);
int len = strlen(str);
int divlen = strlen(div);
for (int i = nBytes, j = nBytes + 1, k = nStrs; i >= 0;--i)
{ // i记录当前位置,j记录上个子串起始位置,l记录当前子串长度,k记录当前子串索引
if (memcmp(&pBytes[i], div, divlen) == 0)
{
int l = j - i - divlen - 1;
j = j - (l + 1); // 重计算为当前子串即将存储的位置
pStrs[--k] = (char*)memmove(&pBytes[j], &pBytes[i + divlen], l);
memset(&pBytes[i], 0, j - i);
}
}
return nStrs;
}



