#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
// return: NULL Not Found
char* s_strstr(const char* _pBegin, int _MaxLen,const char* _szKey)
{
if (NULL == _pBegin || NULL == _szKey || _MaxLen <= 0)
{
return NULL;
}
int i = 0, j = 0, k = 0;
int s32CmpLen = strlen(_szKey);
for (i = 0; i < _MaxLen; i++)
{
if(_pBegin[i] == _szKey[j])
{
for (j = 0, k = i; j < s32CmpLen; j++, k++)
{
if (_pBegin[k] != _szKey[j])
{
j = 0;
break;
}
if (j == s32CmpLen - 1)
{
return (char*)_pBegin + i;
}
}
}
}
return NULL;
}
// return: NULL Not Found
char* s_rstrstr(const char* _pBegin, int _MaxLen,const char* _szKey)
{
if (NULL == _pBegin || NULL == _szKey || _MaxLen <= 0)
{
return NULL;
}
int i = _MaxLen - 1;
int j = strlen(_szKey) - 1;
int k = 0;
int s32CmpLen = strlen(_szKey);
for (i = _MaxLen - 1; i >= 0; i--)
{
if(_pBegin[i] == _szKey[j])
{
for (j = strlen(_szKey) - 1, k = i; j >= 0; j--, k--)
{
if (_pBegin[k] != _szKey[j])
{
j = strlen(_szKey) - 1;
break;
}
if (j == 0)
{
return (char*)_pBegin + i - strlen(_szKey) + 1;
}
}
}
}
return NULL;
}
// return: false error O(n*n)
bool replace(char* _szInput, int _MaxLen, const char* _szOld, const char* _szNew)
{
if (NULL == _szInput || NULL == _szOld || NULL == _szNew || _MaxLen <= 0)
{
return false;
}
bool bRet = true;
char* find = NULL;
do
{
find = s_strstr(_szInput, _MaxLen, _szOld);
if (NULL != find)
{
int BlankLen = _MaxLen - strlen(_szInput);
int NeedLen = strlen(_szNew) - strlen(_szOld);
if (BlankLen >= NeedLen)// check length
{
if (NeedLen >= 0) // 往后移动(空间变大或不变)
{
memmove(find + strlen(_szNew), find + strlen(_szOld), _szInput+ _MaxLen - find - strlen(_szOld) - NeedLen); // prevent overflow
}
else // 往前移动(空间变小)
{
memmove(find + strlen(_szNew), find + strlen(_szOld), _szInput+ _MaxLen - find - strlen(_szOld));
}
memcpy(find, _szNew, strlen(_szNew));
}
else
{
printf("buffer is too small[%d bytes] BlankLen[%d bytes] NeedLen[%d bytes]", _MaxLen, BlankLen, NeedLen);
bRet = false;
break;
}
}
}while(NULL != find);
return bRet;
}
// return: false error O(n)
bool replace1(char* _szInput, int _MaxLen, const char* _szOld, const char* _szNew)
{
if (NULL == _szInput || NULL == _szOld || NULL == _szNew || _MaxLen <= 0)
{
return false;
}
bool bRet = true;
char* find = NULL;
int count = 0;
int offset = 0;
// calculate number of szOld
do
{
find = s_rstrstr(_szInput, _MaxLen - offset, _szOld);
if (NULL != find)
{
count ++;
offset = _szInput + _MaxLen - find;
}
}while (NULL != find);
if (0 == count)
{
return false;
}
int BlankLen = _MaxLen - strlen(_szInput);
int NeedLen = (strlen(_szNew) - strlen(_szOld)) * count;
char* pOldEnd = NULL;
char* pNewEnd = NULL;
// check length
if (BlankLen >= NeedLen)
{
pOldEnd = _szInput + strlen(_szInput); // include '\0'
pNewEnd = _szInput + strlen(_szInput) + NeedLen;
}
else
{
printf("buffer is too small[%d bytes] BlankLen[%d bytes] NeedLen[%d bytes]", _MaxLen, BlankLen, NeedLen);
return false;
}
// replace
if (pNewEnd - pOldEnd < 0)
{
// 往前移动(空间变小)
find = _szInput;
offset = 0;
do
{
find = s_strstr(find, _MaxLen - offset, _szOld);
if (NULL != find)
{
memmove(find + strlen(_szNew), find + strlen(_szOld), _szInput+ _MaxLen - find - strlen(_szOld));
memcpy(find, _szNew, strlen(_szNew));
find += strlen(_szOld);
offset += find - _szInput;
}
}while (NULL != find);
}
else
{
// 往后移动(空间变大或不变)
do
{
find = s_rstrstr(_szInput, pOldEnd - _szInput, _szOld);
if (NULL != find)
{
while (pOldEnd != find + strlen(_szOld) - 1)
{
*pNewEnd -- = *pOldEnd --;
}
memcpy(pNewEnd - strlen(_szNew) + 1, _szNew, strlen(_szNew));
pNewEnd = pNewEnd - strlen(_szNew);
pOldEnd = pOldEnd - strlen(_szOld);
}
}while (NULL != find);
}
return true;
}
int main(int argc, char** argv)
{
if (4 != argc)
{
printf("Usage: %s <str> <key> <key>\n", argv[0]);
return 0;
}
const char* szInput = argv[1];
char* pos = s_strstr(szInput, strlen(szInput), argv[2]);
printf("pos: %s\n", pos);
pos = s_rstrstr(szInput, strlen(szInput), argv[2]);
printf("pos: %s\n", pos);
char str[256];
memset(str, 0, sizeof(str));
strcpy(str, argv[1]);
bool bRet = replace(str, sizeof(str), argv[2], argv[3]);
assert(bRet);
printf("replace: %s\n", str);
memset(str, 0, sizeof(str));
strcpy(str, argv[1]);
bRet = replace1(str, sizeof(str), argv[2], argv[3]);
assert(bRet);
printf("replace1: %s\n", str);
return 0;
}
从内存中正/反向查找特定字符串,字符串替换的2种方法
最新推荐文章于 2023-03-15 14:03:37 发布