JamesSchumacher
April 20th, 2003, 05:17 PM
Trying to recode my Replaced() member function of my ApxString class to replace in a new buffer instead of in place for speed purposes, here's the code for that function. I put a printf() in here to illustrate a problem I'm having. main() code is first - I'm using Dev C++ with GCC 3.2 if it turns out to be a compiler bug.
int main(int argc, char *argv[])
{
ApxString myString("James James James James James Schumacher");
myString.Replace("James James James James James","James");
system("PAUSE");
return 0;
}
That spits out this:
0 30 31 32 33 34 35 36 37 38 39
If I print out the contents of the string after the replace, it's just "James" without the end.
Relevant because of where I put the the printf() in replace. Here is that function:
unsigned long ApxString::Replace(const char * pStrOld,const char * pStrNew) throw()
{
unsigned long dwStringsReplaced(0);
if (pStrOld != 0 && pStrNew != 0)
{
const unsigned long dwOldLen = ::ApxStringLen<char>(pStrOld);
if (dwOldLen != 0)
{
const unsigned long dwNewLen = ::ApxStringLen<char>(pStrNew);
if (dwNewLen != 0)
{
const unsigned long dwStrLen = GetLength();
if (dwOldLen <= dwStrLen)
{
// count how many substrings we have
unsigned long dwSubStringCount(0);
unsigned long dwCharsCounted(0);
bool bDone(false);
for (unsigned long x = 0; x < dwStrLen; ++x)
{
for (unsigned long y = 0; y < dwOldLen; ++y)
{
if (m_pStrData[x + y] == pStrOld[y])
{
++dwCharsCounted;
if (dwCharsCounted == dwOldLen)
{
++dwSubStringCount;
if (x + dwOldLen >= dwStrLen)
{
bDone = true;
}
dwCharsCounted = 0;
break;
}
}
else
{
dwCharsCounted = 0;
break;
}
}
if (bDone == true)
{
break;
}
else if (x + dwOldLen >= dwStrLen)
{
break;
}
}
// Are there any substrings to replace?
if (dwSubStringCount != 0)
{
// check the buffer size we need....
unsigned long dwTempLen = dwStrLen;
dwTempLen -= (dwOldLen * dwSubStringCount);
dwTempLen += (dwNewLen * dwSubStringCount);
const unsigned long dwAlloc = ::ApxDetermineBufferSize(dwTempLen);
// allocate a temporary buffer
char * pTempData = new char[dwAlloc];
if (pTempData != 0)
{
// reuse dwCharsCounted and bDone
dwCharsCounted = 0;
bDone = false;
for (unsigned long t = 0,z = 0; t < dwStrLen; ++t,++z)
{
::printf("%lu ",t);
pTempData[z] = m_pStrData[t];
if (bDone == false)
{
for (unsigned long u = 0; u < dwOldLen; ++u)
{
if (m_pStrData[t + u] == pStrOld[u])
{
++dwCharsCounted;
if (dwCharsCounted == dwOldLen)
{
// found one, copy the new string into the old spot
for (unsigned long p = 0; p < dwNewLen; ++p,++z)
{
pTempData[z] = pStrNew[p];
}
++dwStringsReplaced;
if (t + dwOldLen >= dwStrLen)
{
bDone = true;
}
else
{
t += dwOldLen;
}
dwCharsCounted = 0;
break;
}
}
else
{
dwCharsCounted = 0;
break;
}
}
}
}
// done....
pTempData[dwTempLen] = 0;
delete [] m_pStrData;
m_pStrData = pTempData;
m_dwBufferSize = dwAlloc;
}
}
}
}
}
}
return dwStringsReplaced;
}
I may be tired or something - am I missing something, a simple logic error, or compiler bug
int main(int argc, char *argv[])
{
ApxString myString("James James James James James Schumacher");
myString.Replace("James James James James James","James");
system("PAUSE");
return 0;
}
That spits out this:
0 30 31 32 33 34 35 36 37 38 39
If I print out the contents of the string after the replace, it's just "James" without the end.
Relevant because of where I put the the printf() in replace. Here is that function:
unsigned long ApxString::Replace(const char * pStrOld,const char * pStrNew) throw()
{
unsigned long dwStringsReplaced(0);
if (pStrOld != 0 && pStrNew != 0)
{
const unsigned long dwOldLen = ::ApxStringLen<char>(pStrOld);
if (dwOldLen != 0)
{
const unsigned long dwNewLen = ::ApxStringLen<char>(pStrNew);
if (dwNewLen != 0)
{
const unsigned long dwStrLen = GetLength();
if (dwOldLen <= dwStrLen)
{
// count how many substrings we have
unsigned long dwSubStringCount(0);
unsigned long dwCharsCounted(0);
bool bDone(false);
for (unsigned long x = 0; x < dwStrLen; ++x)
{
for (unsigned long y = 0; y < dwOldLen; ++y)
{
if (m_pStrData[x + y] == pStrOld[y])
{
++dwCharsCounted;
if (dwCharsCounted == dwOldLen)
{
++dwSubStringCount;
if (x + dwOldLen >= dwStrLen)
{
bDone = true;
}
dwCharsCounted = 0;
break;
}
}
else
{
dwCharsCounted = 0;
break;
}
}
if (bDone == true)
{
break;
}
else if (x + dwOldLen >= dwStrLen)
{
break;
}
}
// Are there any substrings to replace?
if (dwSubStringCount != 0)
{
// check the buffer size we need....
unsigned long dwTempLen = dwStrLen;
dwTempLen -= (dwOldLen * dwSubStringCount);
dwTempLen += (dwNewLen * dwSubStringCount);
const unsigned long dwAlloc = ::ApxDetermineBufferSize(dwTempLen);
// allocate a temporary buffer
char * pTempData = new char[dwAlloc];
if (pTempData != 0)
{
// reuse dwCharsCounted and bDone
dwCharsCounted = 0;
bDone = false;
for (unsigned long t = 0,z = 0; t < dwStrLen; ++t,++z)
{
::printf("%lu ",t);
pTempData[z] = m_pStrData[t];
if (bDone == false)
{
for (unsigned long u = 0; u < dwOldLen; ++u)
{
if (m_pStrData[t + u] == pStrOld[u])
{
++dwCharsCounted;
if (dwCharsCounted == dwOldLen)
{
// found one, copy the new string into the old spot
for (unsigned long p = 0; p < dwNewLen; ++p,++z)
{
pTempData[z] = pStrNew[p];
}
++dwStringsReplaced;
if (t + dwOldLen >= dwStrLen)
{
bDone = true;
}
else
{
t += dwOldLen;
}
dwCharsCounted = 0;
break;
}
}
else
{
dwCharsCounted = 0;
break;
}
}
}
}
// done....
pTempData[dwTempLen] = 0;
delete [] m_pStrData;
m_pStrData = pTempData;
m_dwBufferSize = dwAlloc;
}
}
}
}
}
}
return dwStringsReplaced;
}
I may be tired or something - am I missing something, a simple logic error, or compiler bug