Thread: Find and replace function

  1. #16
    Registered User Kolazomai's Avatar
    Join Date
    Aug 2006
    Posts
    12
    Hey!

    In your function 'replaceString' "int count1;" is not initialized. You should assign 0 or any other number to it before you start using it ("while (source[count1] != '\0')").

    Don't you want to use the debugger as I suggested to make your life easier?
    Also, posting the input and corresponding output of your program is always helpful! You should always compile your program with all compiler warnings on (e.g. '-Wall' - use google to find even more to support you). Warnings given to you by the compiler should be treated seriously! With the right settings the compiler would have told you that you missed initializing the variable

    Greetings,
    Kolazomai
    Last edited by Kolazomai; 09-27-2012 at 03:32 AM.

  2. #17
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I'm not sure he's been shown the debugger and etc., that you're referring to. If he can use them, he should.

    He should definitely turn up his warnings on his compiler!

  3. #18
    Registered User
    Join Date
    Sep 2012
    Posts
    49
    I am not sure what compiler you are talking about or how to use it. I definitely would like to use it if you give me some more info.. I am using the make compiler and it didnt catch that count1 was not initialized.. I caught that myself though and now I have no more segmentation error, I just get some weird characters at the end of a correct answer! I am so close but at the end of the correct answer I get like 3 or 4 ascii values that are negative!

  4. #19
    Registered User
    Join Date
    Sep 2012
    Posts
    49
    I see that I get these weird values after the removeString function so I am going to work on that one so that I get a solid '\0' at the end.. If you have any ideas how to fix that function I am all ears because it works as a stand alone function when I just pass something to it from main..

  5. #20
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    If you are running on Windows, I recommend Pelles C (which is both a compiler and an IDE/debugger).

    For Linux or Mac's, I'm not sure, but others will be able to guide you on that. You DEFINITELY want an IDE and debugger, etc.

    I'll see what's up with your program here.

  6. #21
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This works. You can't use just a string literal "let this work one time", kind of parameter, because you can't change a string literal. Well, you can, but you can't without working around the rules of C, just a bit.

    Not going there. Also, I initialized the variable count to 0, as noted in the code.

    Code:
    #include <stdio.h>
    #include <stdbool.h>
    
    void replaceString (char source[],char s1[], char s2[]);
    int  findString (const char  source[], const char  s[]);
    
    int main (void) {
       int i;
       char source[]={"one time let this work"};
       char s1[]= {"1"};
       char s2[]= {"one"};
       
       replaceString(source, "1", "one");
    
       printf("\n");  //added 
       return 0;     //these two lines
    
    } 
    void replaceString (char source[],char s1[], char s2[])
    {
        void removeString (char source[], int i, int remove);
        void insertString (char source[], char insert[], int p);
     
        
        int i = findString(source, s2);
        //printf("i: %d\n",i);getchar();  //just for bug check
    
        int count=0;            //the variable that needed initialization
        
        while (s2[count] != '\0')
           count++;
        
        removeString(source, i, count);
        
        insertString(source, s1, i);
        
        printf("%s\n", source);
    }
    
    int  findString (const char  source[], const char  s[])
    {
        int  i, j, foundit = false;
     
    
        for ( i = 0;  source[i] != '\0'  &&  !foundit;  ++i ) {
            foundit = true;
    
            for ( j = 0;  s[j] != '\0' &&  foundit;  ++j )
                if ( source[j + i] != s[j] || source[j + i] == '\0' )
                  foundit = false;
    
            if (foundit)
               return i;
        }
        
        return -1;
    }
    
    void removeString (char source[], int i, int remove)
    // "i" is where to start removing (from findString) and "remove" is # of characters
    // to remove
    {
        char result[81];
        int j;
        int k = 0;
        
        for (j = 0; j < i; j++)
            result[j] = source[j];
    
        while (source[j + remove] != '\0')
        {
        result[j] = source[j + remove];
        j++;
        }
       
        while (result[k] != '\0')
        {
        source[k] = result[k];
        k++;
        } 
       
       source[k] = '\0';
    }
    
    void insertString (char source[], char insert[], int p)
    // p is where to start inserting and insert[] is what to insert
    {
        int i = 0;
        int j = 0;
        char temp[81];
        
    // convert source to a temp
        while (source[i] != '\0')
        {
        temp[i] = source[i];
        i++;
        }
        temp[i + 1] = source[i + 1];
        
    //change source to insert p     
        while (insert[j] != '\0')
        {
        source[j + p] = insert[j];
        j++;
        }
        
    // add back characters deleted by insertion by taking from temp and place after insert
        while (temp[p] != '\0')
        {
        source[j + p] = temp[p];
        p++;
        }
        source[j + p] = '\0';
        
    }

  7. #22
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Adak View Post
    This works. You can't use just a string literal "let this work one time", kind of parameter, because you can't change a string literal. Well, you can, but you can't without working around the rules of C, just a bit.
    That still breaks in removeString() for the reason Kolazomai mentions in post #9 (result isn't nul-terminated).

    @sdbuilt: Is there a reason why you don't use prototypes ? Your way of declaring functions inside other functions is unusual.

    Bye, Andreas
    Last edited by AndiPersti; 09-27-2012 at 05:49 AM.

  8. #23
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by AndiPersti View Post
    That still breaks in removeString() for the reason Kolazomai mentions in post #9 (result isn't nul-terminated).

    @sdbuilt: Is there a reason why you don't use prototypes ? Your way of declaring functions inside other functions is unusual.

    Bye, Andreas
    I ran the version I posted several times, without error. Are you running a different version?

  9. #24
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    I ran the version from your post #21:
    Code:
    $ gcc -ggdb3 -W -Wall -Wextra -o test test.c
    test.c: In function ‘main’:
    test.c:11:9: warning: unused variable ‘s2’ [-Wunused-variable]
    test.c:10:9: warning: unused variable ‘s1’ [-Wunused-variable]
    test.c:8:8: warning: unused variable ‘i’ [-Wunused-variable]
    $ ./test
    1 time let this work����t:
    
    *** stack smashing detected ***: ./test terminated
    ======= Backtrace: =========
    /lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0x990dd5]
    /lib/i386-linux-gnu/libc.so.6(+0xffd8a)[0x990d8a]
    ./test[0x80484fb]
    /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x8aa4d3]
    ./test[0x80483d1]
    ======= Memory map: ========
    ...
    Aborted (core dumped)
    $ valgrind ./test
    ==3457== Memcheck, a memory error detector
    ==3457== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==3457== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==3457== Command: ./test
    ==3457== 
    ==3457== Conditional jump or move depends on uninitialised value(s)
    ==3457==    at 0x804869F: removeString (test.c:76)
    ==3457==    by 0x804854A: replaceString (test.c:33)
    ==3457==    by 0x80484D7: main (test.c:13)
    ==3457== 
    ...
    Bye, Andreas

  10. #25
    Registered User
    Join Date
    Sep 2012
    Posts
    49
    adak:The code you posted in post #21 ends up having the same problems that I have.. i.e it terminates in a bunch of crazy weird characters instead of a clean null character. Andreas: I went ahead and initialised the result as well as follows:
    Code:
    char result[81] = { 0 };
    and I still am getting the correct answer with weird characters at the end.. Any more ideas?

  11. #26
    Registered User
    Join Date
    Sep 2012
    Posts
    49
    also, I don't use prototypes because I do not know what they are.. I just started learning programming and I am going straight from what they teach me in the book I got (Programming in C by Kochan)

  12. #27
    Registered User
    Join Date
    Sep 2012
    Posts
    49
    bumpety bump!

  13. #28
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Test this out. If it works OK, then the functions in the program, are working OK, and the problem is that the "1" and the "one" were not being treated as strings with an end of string char - which is a common cause of unwanted char's on the end of a string.

    If it fails, then we know that one or more of the functions is causing the error.

    I've tested your program (as I posted in #21 reply above), and in Pelles C, it works correctly. The original program did not, but the version above, works correctly, in limited testing.

    It's not easy to debug a program that keeps working correctly in your compiler!

    Code:
    #include <stdio.h>
    #include <stdbool.h>
    
    void replaceString (char source[],char s1[], char s2[]);
    int  findString (const char  source[], const char  s[]);
    
    int main (void) {
       int i;
       char source[]={"one time let this work"};
       char s1[]= {"1"};
       char s2[]= {"one"};
       
       /*here, s1 and s2 are definitely string arrays, and not merely chars */
       replaceString(source, s1, s2);
    
       printf("\n");  //added 
       return 0;     //these two lines
    
    } 
    void replaceString (char source[],char s1[], char s2[])
    {
        void removeString (char source[], int i, int remove);
        void insertString (char source[], char insert[], int p);
     
        
        int i = findString(source, s2);
        //printf("i: %d\n",i);getchar();  //just for bug check
    
        int count=0;            //the variable that needed initialization
        
        while (s2[count] != '\0')
           count++;
        
        removeString(source, i, count);
        
        insertString(source, s1, i);
        
        printf("%s\n", source);
    }
    
    int  findString (const char  source[], const char  s[])
    {
        int  i, j, foundit = false;
     
    
        for ( i = 0;  source[i] != '\0'  &&  !foundit;  ++i ) {
            foundit = true;
    
            for ( j = 0;  s[j] != '\0' &&  foundit;  ++j )
                if ( source[j + i] != s[j] || source[j + i] == '\0' )
                  foundit = false;
    
            if (foundit)
               return i;
        }
        
        return -1;
    }
    
    void removeString (char source[], int i, int remove)
    // "i" is where to start removing (from findString) and "remove" is # of characters
    // to remove
    {
        char result[81];
        int j;
        int k = 0;
        
        for (j = 0; j < i; j++)
            result[j] = source[j];
    
        while (source[j + remove] != '\0')
        {
        result[j] = source[j + remove];
        j++;
        }
       
        while (result[k] != '\0')
        {
        source[k] = result[k];
        k++;
        } 
       
       source[k] = '\0';
    }
    
    void insertString (char source[], char insert[], int p)
    // p is where to start inserting and insert[] is what to insert
    {
        int i = 0;
        int j = 0;
        char temp[81];
        
    // convert source to a temp
        while (source[i] != '\0')
        {
        temp[i] = source[i];
        i++;
        }
        temp[i + 1] = source[i + 1];
        
    //change source to insert p     
        while (insert[j] != '\0')
        {
        source[j + p] = insert[j];
        j++;
        }
        
    // add back characters deleted by insertion by taking from temp and place after insert
        while (temp[p] != '\0')
        {
        source[j + p] = temp[p];
        p++;
        }
        source[j + p] = '\0';
        
    }
    Try that, with several different s1 and s2 strings.

  14. #29
    Registered User
    Join Date
    Sep 2012
    Posts
    49
    Ok I did as you said and tried that code.. (I had to take out the "i" variable in main as it was not used but it compiled after that).. after trying to use s1 as both "1" and "two" and s2 as both "one" and "time" I still am not getting a proper null at the end. I end up with weird shaded in question marks or random letters or slashes at the end of an otherwise correct statement. So I believe from the debugging I did earlier that that means that the problem is in the removeString function. However I cannot find anything wrong with that function. It works fine when I hand something to it from main.. Any ideas on maybe how to rewrite that function or why it might not be working?

  15. #30
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Two things:

    1) you have an int variable named "remove". Rename it as "remove1" or something else. "remove" is a C keyword to delete a file, and that might cause a problem.

    2) add the print loop for the source array, at the end of every function, one at a time, until you find the offending function putting the extra chars into the string.

    Weird that it works one way, but not the other.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Find and replace
    By yoghesh11 in forum C++ Programming
    Replies: 9
    Last Post: 05-14-2012, 12:54 AM
  2. function to find and replace a part of a string
    By 9988776655 in forum C Programming
    Replies: 2
    Last Post: 02-02-2008, 01:39 AM
  3. please help!...find and replace
    By amy589 in forum C++ Programming
    Replies: 26
    Last Post: 10-13-2006, 06:42 PM
  4. Find and replace
    By BobDole1 in forum C++ Programming
    Replies: 1
    Last Post: 04-12-2003, 10:06 PM
  5. Find and Replace Text Function
    By mart_man00 in forum C Programming
    Replies: 45
    Last Post: 03-13-2003, 10:21 PM