>>OK, OK, damn and blast,
>>Rereading your post, you are technically correct
Damn, I'd just written a nice reply too. Oh well, I've deleted it and I'll make my summary by quoting myself:
>>strncpy() ... isn't guaranteed to write a nul
We're done
>>OK, OK, damn and blast,
>>Rereading your post, you are technically correct
Damn, I'd just written a nice reply too. Oh well, I've deleted it and I'll make my summary by quoting myself:
>>strncpy() ... isn't guaranteed to write a nul
We're done
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
i was about to fix up the replace function up alittle more and i attempt to but the process in a loop in case string search is in src a couple times
my while loop never ends, why? i thought the fact that a pointer is never NULL would make this work. unfortunally im doing this in windows again, but if its wrong why wouldnt i get a seg fault for checking out memory thats not mine?Code:int replace(char *src, char search[], char replace[]) { char *value = malloc( strlen(src) - strlen(search) + strlen(replace) +1 ); char *found; while(found != NULL) { /* never ends, why? */ found = strstr(src, search); } printf("%s", value); free(value); return 0; }
>>found = strstr(src, search);
strchr() is being asked to look for the same thing each time the loop goes round, so it will return the same answer.
Also, the value of found is undefined the first time into the loop.
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
doesnt it increment itself so it can look for a string more than once? can i make it?strchr() is being asked to look for the same thing each time the loop goes round, so it will return the same answer.
No. It doesn't. No, you can't. That is to say, you can't change the function itself. You can change what you pass to it:Originally posted by mart_man00
doesnt it increment itself so it can look for a string more than once? can i make it?
That should work. Initialize it by having the return value of the initialization be stored in 'something'. Use subsequent calls to check 'something', updating it on each call.Code:for( something = strchr( somestring, somechar ); sometest; something = strchr( something +1, somechar ) );
Naturally you'll want better error checking than what I use.
Quzah.
Hope is the first step on the road to disappointment.
>>doesnt it increment itself so it can look for a string more than once?
No, you need to update the pointers you pass to strstr() each time.
[edit]Doh, beatenCode:#include <stdio.h> #include <string.h> int main(void) { char buf[] = "this is something is blah is OK"; char *p; puts(buf); for (p = buf; p = strstr(p, "is"); p++) puts(p); return(0); } /* * Output: this is something is blah is OK is is something is blah is OK is something is blah is OK is blah is OK is OK */
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
i tried to rewrite my function so it will look more than once, but with no luck. any one see why?
Code:int replace(char *src, char search[], char replace[]) { char *value = malloc(strlen(src) - strlen(search) + strlen(replace) + 1 ); char check[ strlen(src) + 1 ]; char *found = src; char *spot = src; while(*spot != '\0' && found != NULL) { found = strstr(spot, search); if( strcmp(found, check) != 0 ) { printf("%s\n", found); strncat(value, spot, found - src); strcat(value, replace); strcat(value, found + strlen(search)); printf("\t%s\n", value); } strcpy(check, found); ++*spot; } free(value); return 0; }
Never assume passed argument pointers are non-NULL. Always check before using them.Code:char *value = malloc(strlen(src) - strlen(search) + strlen(replace) + 1 );
Variable length arrays are not part of the pre-C99 standard. It's doubtful your compiler actually is a C99 compiler. Avoid this.Code:char check[ strlen(src) + 1 ];
Why are you dereferencing this pointer? You shouldn't be.Code:strcpy(check, found); ++*spot;
Finally, what is the purpose of value? Debugging, or what?
Quzah.
Hope is the first step on the road to disappointment.
value is a just a temp varible to work with, it will eventually get copied to src.
im using gcc for this, and it works, just only once. char check[ strlen(src) + 1 ]; doesnt seem right, atleast with my malloc call i get exactly how much i need.
im really not sure what to do here now, im alittle confused. i dont see why this wouldnt work. how would you guys do this?
Um... that line of code is from your example. I was pointing out that variable sized arrays, such as the one listed above, is not part of the pre-C99 standard. (IE: It's bad form.)Originally posted by mart_man00
char check[ strlen(src) + 1 ]; doesnt seem right, atleast with my malloc call i get exactly how much i need.
Quzah.
Hope is the first step on the road to disappointment.
can any one show me how they would write this function, im getting now where. i just want it to scan a string for a string and replace ever occurence.
heres my most recent failure
i think its time to learn by example.............................Code:int replace(char *src, char search[], char replace[]) { char *value = malloc( strlen(src) + 1); value[0] = '\0'; char *spot = src; char *found = src; char check[ strlen(src) ]; while(spot != NULL && (found = strstr(spot, search)) != NULL ) { if( strcmp(found, check) != 0 ) { realloc(value, strlen(found) + 1); /* Problem here, how do i find the length of everything before found? */ strncat(value, spot, found - src); realloc(value, strlen(replace) + 1); strcat(value, replace); realloc(value, strlen(found) + 1); strcat(value, found + strlen(search)); } printf("\n%s\n", value); strcpy(check, found); ++spot; } free(value); strcpy(src, value); return 0; }
im also getting garbage data somewhere.
This will search and replace with larger or smaller text. First count the number of replacements then allocate a new buffer from the count, then copy the old buffer+replacement text to the new buffer in the while loop.
Code:#include <stdio.h> #include <string.h> #include <stdlib.h> void replace(char **newbuffer, char *source, char *search, char *replace) { int count=0,slen = strlen(search),rlen = strlen(replace); char *s1 = source; while(s1 = strstr(s1, search)) { count++; s1 += slen; } // char *n1 = *newbuffer = new char[ strlen(source)+((strlen(replace)-slen)* count)+1 ]; char *n1 = *newbuffer = (char *) malloc( strlen(source)+((strlen(replace)-slen)* count)+1 ); s1 = source; while(s1 = strstr(s1, search)) { strncpy(n1,source, s1-source); n1 += s1-source; strcpy(n1,replace); n1 += rlen; s1 += slen; source = s1; } strcpy(n1, source ); } int main() { char temp2[] = "testing a new idea, testing a new idea, testing a new idea"; char *newbuffer; //replacing with larger replace(&newbuffer, temp2, "new", "WORKING"); printf("%s\n", newbuffer); // delete [] newbuffer; free(newbuffer); //replacing with smaller replace(&newbuffer, temp2, "new", "X"); printf("%s\n", newbuffer); // delete [] newbuffer; free(newbuffer); return 0; }
Last edited by Scarlet7; 03-07-2003 at 05:37 PM.
For the record, delete and new are C++ operators, and are not available in C.
Quzah.
Hope is the first step on the road to disappointment.
I was just showing the program structure, but just replace 'new' and 'delete' with the following code 'malloc()' and 'free()':
I have corrected the post,Code:char *n1 = *newbuffer = (char *) malloc( strlen(source)+((strlen(replace)-slen)* count)+1 ); free(newbuffer);
Cheers....
Last edited by Scarlet7; 03-07-2003 at 05:39 PM.
Thanks Scarlet7,
I have been wrestling with a way to implement replacing of multiple instances of multiple different place holders in a string.
Your way will work very nicely and about ten times more efficiently than what I had been thinking of.
I think it will be something like this:
Code:struct found { lpstr placeholder lpstr replace lpstr position } for (loop through placeholders) while _tcsstr(src, placeholders[i]) { add replace length to length needed add found pointer to array of found structs } } sort array of found structs by the position member so that those first in the string are first in the array. allocate required mem for dest for (loop through array of found structs.) { memcpy(dest,src, foundstruct[i].position - src) dest+= (.position - src) src = .position + strlen(.placeholder) memcpy(dest, .replace, strlen(replace) ) dest += strlen(replace); }