Thread: Find and Replace Text Function

  1. #1
    Registered User
    Join Date
    Jul 2002
    Posts
    913

    Find and Replace Text Function

    im working on a find and replace text function now, with not alot of luck

    heres what i have so far
    Code:
    int replace(char *source, char search[], char replace[]) {
        char *value = (char *)malloc( ( strlen(source) - strlen(search) ) + strlen(replace) );
    
        char *start = strstr(source, search);
        strncpy(value, source, *start); 
        
        printf("%s\n", value);
        
        return 0;
    }
    
    int main() {
        char temp[] = "testing a new idea";
        replace(temp, "new", "WORKING");
    
    
        return 0;
    }
    i want to look for string search in string source and copy it to a seperate string. then i want to strcat the replace and copy what was left over from string.

    right now the strncpy(value, source, *start); line doesnt seem to be working. i now its a memory adress im giving it, but is there and way i can use it like a subscript?

    i was think about making a function to figure out the subscript from the address and the string name, but it really cant be done. characters can repeat them self.

  2. #2
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    i was think about making a function to figure out the subscript from the address and the string name, but it really cant be done. characters can repeat them self.
    if there isnt another solution, couldnt i play with the address themselves? i mean take the char's address and subtract from the first char in string and divide by how big a char is? how could i get the first node's address(making a pointer to it seems like a waste)? can i assign pointers by addresses(is that a good idea in a os like linux)?

    to many questions, to little code..........

  3. #3
    not much here
    Guest
    Code:
    int replace(char *source, char search[], char replace[]) {
    /* We add 1 to account for the null terminator */
        char *value = (char *)malloc( ( strlen(source) - strlen(search) ) + strlen(replace) + 1 );
    
    /* check malloc */
        if (value == NULL) return 0;
    
    /* null initialise value */
        value[0] = '\0';
    
        char *start = strstr(source, search);
    /* check that search was found */
        if (start == NULL) return 0;
    
        /* We get number of characters by taking source address from
            start address. We use strncat as it always appends a 
            null while strncpy does not. This is why we null initialised
            value */
        strncat(value, source,(int) start - (int) source); 
    
        /* Append the replacement */
        strcat(value,replace);
    
        /* Append the rest of the string following the search string */
        strcat(value,start + strlen(replace) );
    
        printf("%s\n", value);
        
        return 0;
    }
    Seeing your second post I think you have the idea. Good luck.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    The biggest problem with this design is if the replacement string is larger than the search string, there's no safe way to determine whether the pointer you get can be realloc'd, so you're stuck with assuming that the size is fixed and that the replacement would overrun the boundaries. You'll have to settle with returning a completely new string and have the caller handle copying into the source string:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    static char *replace ( const char *src, const char *find, const char *repl )
    {
      char *found;
      /*
      ** Create enough space for the source string
      ** and the replacement string to be added.
      ** Don't forget one slot for the nul char.
      */
      char *new_src = malloc ( strlen ( src ) + strlen ( repl ) + 1 );
    
      /* No recovery possible, return failure */
      if ( new_src == NULL )
        return NULL;
    
      found = strstr ( src, find );
    
      /* Search string not found, return the whole of the source */
      if ( found == NULL ) {
        strcpy ( new_src, src );
        return new_src;
      }
    
      /* Paste the replacement string in */
      strncpy ( new_src, src, (size_t)(found - src) );
      strcat ( new_src, repl );
      strcat ( new_src, found + strlen ( find ) );
    
      return new_src;
    }
    
    int main ( void )
    {
      char *modified;
      char a[] = "This is a test";
    
      modified = replace ( a, "a", "another" );
    
      puts ( modified );
      free ( modified );
    
      return 0;
    }
    And to all previous posters, always free your allocated memory.

    -Prelude
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    not much here, the last part of your code doesnt work right. the strcat part doesnt copy all of the remaining test. thanks for the begining tho.

    prelude, your code works, but i dont understand how. why wont strcat(value, start + strlen(replace)); work correctly?

    thanks

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >prelude, your code works
    I sure hope so. Posting broken code is embarassing

    >but i dont understand how
    This is a good time to walk through the code with a debugger, that way you can see exactly what changes are being made:
    Code:
    --static char *replace ( const char *src, const char *find, const char *repl )
    src = "This is a test"
    find = "a"
    repl = "another"
    
    --found = strstr ( src, find );
    found = "a test"
    
    --strncpy ( new_src, src, (size_t)(found - src) );
    found - src = 8
    new_src = "This is "
    
    --strcat ( new_src, repl );
    new_src = "This is another "
    
    --strcat ( new_src, found + strlen ( find ) );
    found + strlen ( find ) = " test"
    new_src = "This is another test"
    -Prelude
    My best code is written with the delete key.

  7. #7
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    why wont something like this work right?

    Code:
    int replace(char *src, char find[], char replace[]) {
        char *value = malloc( strlen(src) - strlen(find) + strlen(replace) + 1 );
            strcpy(value, src);
            
        char *found = strstr(value, find);
    
        value[*found] = '\0';
        strcat(value, replace);
        strcat(value, found + strlen(replace));
    
        printf("%s", value);
        strcpy(src, value);
        free(value);
        
        return 0;
    }

  8. #8
    Registered User
    Join Date
    Jan 2003
    Posts
    78
    What if the block value points to is smaller than the string source points to?

  9. #9
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    lets see if i got this right now, you can give strcat a position and it keeps going until it finds a \0? so it does do it char by char?

    so why doesnt this compile(the addto function)?
    Code:
    int copy(char *src, char *dest, int *start, int end) {
        char *value = (char *)malloc(end - *start);
        int x = 0;
        
        if(end == 0)
            end = strlen(src);
        
        while(src[*start] < end) {
            value[x] = src[*start];
            
            ++x;
            ++*start;
        }
        
        return 0;
    }
    
    int addto(char *src, char data[], int start) {
        char value[ strlen(src) ];
            strcpy(value, src);
        char buff[ strlen(src) - start + 1 ];
            
        value[start] = '\0';
        strcat(value, data);
        strcat(value, src[start]);
        
        printf("%s\n", value);
        
        return 0;
    }
    
    int main() {
        char temp[25] = "testing a new idea";
        addto(temp, "working", 14);
    
        return 0;
    }
    it doesnt like the strcat(value, src[start]); part, but why? start is a number and a number is a subscript.

  10. #10
    not much here
    Guest
    Code:
    strcat(value,start + strlen(replace) );
    
    should of course read:
    
    strcat(value,start + strlen(search) );
    My apologies.

  11. #11
    not much again
    Guest
    Prelude, your code is essentially the same as mine (without the small bug).
    However:
    Code:
    strncpy ( new_src, src, (size_t)(found - src) );
    strcat ( new_src, repl );
    The docs say that strncpy does not append a null character. So this should fail unless new_src is all nulls.

    http://www.opengroup.org/onlinepubs/...s/strncpy.html

  12. #12
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>The docs say that strncpy does not append a null character.
    OK, I'm late into this conversation, but... This statement is incorrect, and your link proves it:
    If the array pointed to by s2 is a string that is shorter than n bytes, null bytes shall be appended to the copy in the array pointed to by s1, until n bytes in all are written.
    So, in short is isn't guaranteed to write a nul, but providing the string fits, it will.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  13. #13
    not much duel
    Guest
    I challenge you to a duel at dawn. :-)
    Code:
    char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
    You should reread the entire documentation.
    If the array pointed to by s2 is a string that is shorter than n bytes, null bytes shall be appended to the copy...
    If string s2 is shorter that n bytes then we do not need to use strncpy we could just use strcpy. The whole idea of strncpy is that we want to copy only the first n bytes from s2.
    Code:
    char s1[50]; /* random data */
    char s2[] = "We want to copy the first 10 chars of s2";
    strncpy(s1,s2,10); /* s2 is not shorter than n bytes */
    s1 now contains the first ten chars of s2 and is not null terminated.
    If you had read the entire doc you would have found this:
    If there is no null byte in the first n bytes of the array pointed to by s2, the result is not null-terminated.
    I'm sure you would agree that there is no null byte in the first ten characters of s2 above.

    Code:
    strncpy ( new_src, src, (size_t)(found - src) );
    Again, there is no null in the first n bytes of src.

    This would work:
    Code:
    char s1[50];
    char s2[] = "test";
    strncpy(s1,s2,50); /* = strcpy(s1,s2); */
    but is a pointless exercise.

    or from MSDN:
    If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string.

  14. #14
    not much more
    Guest
    Code:
    char * strncpy(char * s1, char * s2, size_t n) {
    	memset(s1, 0, n);
    	memcpy(s1, s2, min(strlen(s2), n) );
    }

  15. #15
    damnandblast
    Guest
    OK, OK, damn and blast,
    Rereading your post, you are technically correct. Although , practically and in the context of this thread your info is still quite useless.

    If I bothered to sign in I wouldn't make such a fool of myself.
    Ah well, that's life.

    To finish this discussion, there is three ways to use strncpy.
    A. Make sure your destination string is null filled before using it.
    B. Null terminate your destination string after using strncpy.
    C. Accept that the destination string will not be null terminated. Ie. Treat it like binary data.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Find and replace within a string?
    By clancyPC in forum C Programming
    Replies: 3
    Last Post: 03-20-2009, 07:28 AM
  2. please help!...find and replace
    By amy589 in forum C++ Programming
    Replies: 26
    Last Post: 10-13-2006, 06:42 PM
  3. Bisection Method function value at root incorrect
    By mr_glass in forum C Programming
    Replies: 3
    Last Post: 11-10-2005, 09:10 AM
  4. Find Dialog
    By Lithorien in forum Windows Programming
    Replies: 6
    Last Post: 04-25-2005, 05:28 PM
  5. Find and replace
    By BobDole1 in forum C++ Programming
    Replies: 1
    Last Post: 04-12-2003, 10:06 PM