spinoza1111 wrote:
Seebie posted what I considered a crude, and what he admitted to be a
buggy, solution to the "problem of replacing %s by a string".
He redefined the problem as "searching for a character", in my view
incorrectly, and produced a special-purpose and IMO rather confusing
solution. He admitted that the solution would not work if other
percent sequences or signs existed in the input.
Two hours ago I started to write and to test the following solution,
which is based on my discussion of the failings of Seebie's code, and
my demonstration above in prose that the REAL problem is "replacing a
string, where a string is not terminated by NUL", and that if instead
of "hacking" the problem (reducing it to something we can solve
"simply" whilst creating, as I've shown, a problem when you return to
fix the admitted problem), we actually ANALYZE the problem like men.
The code below does what I propose above: in one pass it finds all the
replacement strings and simultaneously constructs a linked list of
segments outside of replacement strings. In a subsequent half a pass
it assembles the final string.
The code has only been tested for two cases but it's time to let you
slobs have at it.
Here is the code. Hungarian notation is used without apology: note
that string names not intended to be used as pointers start with str,
whereas string pointers intended to be used as such start with ptr. I
will continue to test it and post further improvements as they become
available.
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
struct TYPsegmentstruct
{ char * strSegment;
long lngSegmentLength;
int intReplaceAtEnd;
struct TYPsegmentstruct * ptrNext; };
char * replace(char * strMaster,
char * strTarget,
char * strReplacement)
{
char * ptrIndex0;
char * ptrIndex1;
char * ptrIndex2;
char * ptrIndex3;
char * strNew;
char * strNewStart;
long lngNewLength;
long lngCount;
struct TYPsegmentstruct * ptrSegmentStructStarts;
struct TYPsegmentstruct * ptrSegmentStruct;
struct TYPsegmentstruct * ptrSegmentStructPrev;
ptrIndex1 = strMaster;
ptrSegmentStructPrev = 0;
lngNewLength = 0;
while(*ptrIndex1)
{
ptrIndex0 = ptrIndex1;
for(;
*ptrIndex1 && *ptrIndex1 != *strTarget;
ptrIndex1++);
for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
*ptrIndex3 && *ptrIndex2 && *ptrIndex3 == *ptrIndex2;
ptrIndex3++, ptrIndex2++);
if (!*ptrIndex1 || !*ptrIndex2)
{
if (!(ptrSegmentStruct =
malloc(sizeof(struct TYPsegmentstruct))))
abort();
ptrSegmentStruct->strSegment = ptrIndex0;
ptrSegmentStruct->lngSegmentLength =
ptrIndex1 - ptrIndex0;
ptrSegmentStruct->intReplaceAtEnd =
!*ptrIndex2 ? -1 : 0;
lngNewLength += ptrSegmentStruct->lngSegmentLength +
(*ptrIndex1
?
strlen(strReplacement)
:
0);
ptrSegmentStruct->ptrNext = 0;
if (ptrSegmentStructPrev != 0)
ptrSegmentStructPrev->ptrNext = ptrSegmentStruct;
else
ptrSegmentStructStarts = ptrSegmentStruct;
ptrSegmentStructPrev = ptrSegmentStruct;
}
ptrIndex1 = ptrIndex3;
}
if (!(strNewStart = malloc(lngNewLength + 1))) abort();
strNew = strNewStart;
ptrSegmentStruct = ptrSegmentStructStarts;
while (ptrSegmentStruct)
{
for (ptrIndex1 = ptrSegmentStruct->strSegment,
lngCount = 0;
lngCount < ptrSegmentStruct->lngSegmentLength;
ptrIndex1++, lngCount++, strNew++)
*strNew = *ptrIndex1;
if (ptrSegmentStruct->intReplaceAtEnd)
for (ptrIndex1 = strReplacement;
*ptrIndex1;
ptrIndex1++, ++strNew)
*strNew = *ptrIndex1;
ptrSegmentStruct = ptrSegmentStruct->ptrNext;
}
*strNew = '\0';
return strNewStart;
}
int main()
{
printf("\nReplace\n\n\n");
printf("Expect a miracle:\n\"%s\"\n\n",
replace("a stupid error", "stupid error", "miracle"));
printf("Expect a miracle error:\n\"%s\"\n\n",
replace("a stupid error", "stupid", "miracle"));
return 0;
}
It doesn't compile here. I'm using gcc 4.3.3 on Ubuntu 9.04.
$ gcc -o spinoza1111 spinoza1111.c
spinoza1111.c:27:16: error: invalid suffix "D" on integer constant
spinoza1111.c: In function ‘replace’:
spinoza1111.c:27: error: expected ‘;’ before ‘strMaster’
spinoza1111.c:28:27: error: invalid suffix "D" on integer constant
spinoza1111.c:28: error: expected ‘;’ before numeric constant
spinoza1111.c:29:19: error: invalid suffix "D" on integer constant
spinoza1111.c:29: error: expected ‘;’ before numeric constant
spinoza1111.c:32:20: error: invalid suffix "D" on integer constant
spinoza1111.c:32: error: expected ‘;’ before ‘ptrIndex1’
spinoza1111.c:34:40: error: invalid suffix "D" on integer constant
spinoza1111.c:36:24: error: invalid suffix "D" on integer constant
spinoza1111.c:36: error: expected ‘;’ before ‘strTarget’
spinoza1111.c:36:49: error: invalid suffix "D" on integer constant
spinoza1111.c:37:53: error: invalid suffix "D" on integer constant
spinoza1111.c:37:56: error: invalid suffix "D" on integer constant
spinoza1111.c:41:37: error: invalid suffix "D" on integer constant
spinoza1111.c:42: error: expected ‘)’ before ‘malloc’
spinoza1111.c:44:43: error: invalid suffix "D" on integer constant
spinoza1111.c:44: error: expected ‘;’ before ‘ptrIndex0’
spinoza1111.c:45:49: error: invalid suffix "D" on integer constant
spinoza1111.c:46: error: expected ‘;’ before ‘ptrIndex1’
spinoza1111.c:47:48: error: invalid suffix "D" on integer constant
spinoza1111.c:48: error: expected ‘;’ before ‘!’ token
spinoza1111.c:49:28: error: invalid suffix "D" on integer constant
spinoza1111.c:49: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:55:40: error: invalid suffix "D" on integer constant
spinoza1111.c:55: error: expected ‘;’ before numeric constant
spinoza1111.c:56:40: error: invalid suffix "D" on integer constant
spinoza1111.c:56: error: expected ‘)’ before numeric constant
spinoza1111.c:57:48: error: invalid suffix "D" on integer constant
spinoza1111.c:57: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:59:41: error: invalid suffix "D" on integer constant
spinoza1111.c:59: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:60:35: error: invalid suffix "D" on integer constant
spinoza1111.c:60: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:62:20: error: invalid suffix "D" on integer constant
spinoza1111.c:62: error: expected ‘;’ before ‘ptrIndex3’
spinoza1111.c:64:24: error: invalid suffix "D" on integer constant
spinoza1111.c:64: error: expected ‘)’ before ‘malloc’
spinoza1111.c:65:13: error: invalid suffix "D" on integer constant
spinoza1111.c:65: error: expected ‘;’ before ‘strNewStart’
spinoza1111.c:66:23: error: invalid suffix "D" on integer constant
spinoza1111.c:66: error: expected ‘;’ before ‘ptrSegmentStructStarts’
spinoza1111.c:69:25: error: invalid suffix "D" on integer constant
spinoza1111.c:69: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:70:24: error: invalid suffix "D" on integer constant
spinoza1111.c:73:23: error: invalid suffix "D" on integer constant
spinoza1111.c:75:29: error: invalid suffix "D" on integer constant
spinoza1111.c:75: error: expected ‘;’ before ‘strReplacement’
spinoza1111.c:78:27: error: invalid suffix "D" on integer constant
spinoza1111.c:79:27: error: invalid suffix "D" on integer constant
spinoza1111.c:79: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:81:14: error: invalid suffix "D" on integer constant
spinoza1111.c:81: error: expected ‘;’ before '\x0'
How did it compile for you? Which compiler and what options did you
use?