1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Implementing strcat without string.h in C

  1. Oct 27, 2014 #1
    Hi everyone. This is similar to my strcpy question previously. I tried to code but when I ran the code, a segmentation fault appears. I think this has something to do with my loop for the array but I have problems resolving it. May I have some help please? Thank you. My codes and the original question are below:

    Question: Implement the my_strcat(s1,s2) function to append a copy of string s2, including the terminating null character, to the end of string s1. The initial character of s2 overrides the null character at the end of s1. String s1 is returned.

    Use the function "char *my_strcat(char *s1, const char *s2);"

    Code (Text):

    #include <stdio.h>
       char *my_strcat(char *s1, const char *s2);
       int main(void)
       {
           char str1[40]={"goose"};
           char str2[40]={"berry"};
           char* s1;
           char* s2;
           char* type_berry;
     
          type_berry = my_strcat(s1, s2);
     
          printf("%s\n", *type_berry);
          return 0;
      }
     
      char *my_strcat(char *s1, const char *s2)
      {
          int i=0, j=0, count=0;
     
          while(s1[i] != '\0')
          {
              count = count + 1;
              i++;
          }
     
          i = count;
     
          while(s2[j]!= '\0')
          {
              s1[i]= s2[j];
              i++;
              j++;
          }
     
          return s1;
      }
     
    I think, after catting the 2 strings, I should get in C terms, gooseberry(\0). \0 is the last null char occupying the last box of the str, which is a char array.
     
  2. jcsd
  3. Oct 28, 2014 #2

    DrClaude

    User Avatar

    Staff: Mentor

    There are many things wrong with your code. I'll point out a few:
    What is the value of s1 and s2 at this point?

    Why do you have both count and i as variables?

    Do you guarantee that string s1 will end properly?
     
  4. Oct 28, 2014 #3
    Hi DrClaude. Oh dear. Hmm.. I need to think about my answers to the other questions, but I had:
    Code (Text):
    while(s1[i] != '\0')
          {
              count = count + 1;
              i++;
          }
    i = count;
    because I wanted to join str2[0] to str1[5]. However, when i reaches 4 for str1, s1[4] will be pointing at str1[4], but I need to replace str1[5], the NULL char with str2[0], thus I put "i = count" after the while loop since count would be 5 at that time.
     
  5. Oct 28, 2014 #4
    I am not very sure what are the values for s1 and s2, but when I return s1 from the my_strcat function, type_berry should bear the pointer s1 and thus when I print it out, it should give me gooseberry'\0'. This is my thought process (which I think may not be correct).. :(
     
  6. Oct 28, 2014 #5
    I tried to put:
    Code (Text):

    while(s2[j]!= '\0' && s1[i] != '\0'){
    {
        s1[i]= s2[j];
        i++;
        j++;
    }

      return s1;
    }
     
    but I got a seg. fault again. T.T
     
  7. Oct 28, 2014 #6

    DrClaude

    User Avatar

    Staff: Mentor

    I'll ask again. When the program reaches the line
    Code (C):

    type_berry = my_strcat(s1, s2);
     
    what are s1 and s2 pointing to?

    Before the while loop, both count and i are equal to 0. They are both incremented by 1 at each iteration. After the loop, i is replaced by count. You are basically counting the same thing twice.
     
  8. Oct 28, 2014 #7
    I think s1 is pointing to str1[9], while s2 is pointing to str2[5]. I don't think I am correct as the bottom-most while loop doesn't seem to be controlled correctly. ><

    I see. Hmm.. I was thinking when i=0, count = 1, since count would have incremented from 0 to 1 before i=0 increments to i=1 at i++. Am I wrong? ><
     
  9. Oct 28, 2014 #8

    Mark44

    Staff: Mentor

    DrClaude is asking about this code in your main() function. His question was "What are s1 and s2 pointing to?" Your reply above is not correct. Take a closer look at it.
     
  10. Oct 28, 2014 #9
    Oh my gosh!! I forgot to set where s1 and s2 are pointing to! T_T I'm so sorry. :( I will edit my code again and see what happens. My apologies DrClaude and Mark44.
     
  11. Oct 28, 2014 #10
    I have edited my codes and I shall re-post them here, which I hope will make referencing to my code easier. Thank you. Sorry. I can't believe I took so long to see my mistake. Sigh~

    Code (Text):

    #include <stdio.h>

    char *my_strcat(char *s1, const char *s2);

    int main(void)
    {
        char str1[40]={"goose"};
        char str2[40]={"berry"};
        char* s1;
        char* s2;
        char* type_berry;

        s1 = &str1[0];
        s2 = &str2[0];

        type_berry = my_strcat(s1, s2);

        printf("%s\n", *type_berry);
        return 0;
    }

    char *my_strcat(char *s1, const char *s2)
    {
        int i=0, j=0, count=0;

        while(s1[i] != '\0')
        {
            count = count + 1;
            i++;
        }
        i = count;

       while(s2[j]!= '\0'&& s1[i]!= '\0')
       {
              s1[i]= s2[j];
              count++;
              j++;
       }
       s1[i] = '\0';
       return s1;
    }
     
     
  12. Oct 28, 2014 #11

    Mark44

    Staff: Mentor

    Without commenting on the validity of your code, there are some shortcuts you can take.

    You don't need braces { } when you initialize an array of char. You can do this:
    Code (Text):
    char str1[40] = "goose";
    If the array is of some other type than char, you still need the braces.

    Also, you can let the compiler figure out how much space to allocate for an initialized array. IOW, you can do this:
    Code (Text):
    char str1[] = "goose";
    Here the compiler will allocate enough space the characters of the string + a terminating null character. If you're going to be concatenating additional characters onto the string, then it's fine to specify how big the array should be. Since you're not doing anything to the str2 array, you could declare it similar to the above.

    You can declare and initialize a pointer in one statement, like so:
    Code (Text):
    char * s1 = str1;
    str1 is the same as &str1[0]. The name of an array evaluates to the address of the first element of the array.
     
  13. Oct 29, 2014 #12

    DrClaude

    User Avatar

    Staff: Mentor

    This part is broken.
     
  14. Oct 29, 2014 #13
    To Mark44:

    I see. I will note down your tips and tricks and perhaps use them for the final exams! Hopefully, I can save some time by writing 'less' code. Haha. :)

    To DrClaude:

    I see. But after staring at it for some time, I still can't write a correct code. May I have some hints please?
    My teacher went through the answer during class today but he used a combination of string functions (which were coded by him, i.e. not from string.h library) to solve the question. :O
     
  15. Oct 29, 2014 #14
    You've already made the necessary corrections.
    Your "my_strcat" that you originally posted is basically correct with two exceptions:
    1) Get rid of all references to "count". You aren't using that value.
    2) You need to terminate the s1 string with s1='\0';

    That first attempt was better than your second.
     
  16. Oct 29, 2014 #15

    DrClaude

    User Avatar

    Staff: Mentor

    Staring is not useful here. "Execute" the code with pen and paper and see what you get.

    If you compile the code in post #10, you get a warning, and the resulting executable ends with a segmentation fault, that means you didn't test it before posting.

    When you have a segmentation fault, you can use a debugger to help you. Compile the code with the -g flag, then run it using gdb:
    gdb ./a.out

    then at the prompt, type run. When the segmentation fault happens, the debugger will tell you which line was at fault.
     
  17. Oct 29, 2014 #16
    To DrClaude:

    This is the reason why I posted this here... I have vim, so I can compile the codes I write, and for this, I kept getting segmentation fault no matter what I did.

    However, after figuring out a little, I think I should remove the 2nd condition in the 2nd while loop, if not, the 2nd while loop will never run, as it will be while(true&&false). I will post my code separately together with my trace.

    Does the debugger work for all types of errors? This is because vim will give you the line number at which the error appears and one can look for the line and try to see what has happened. Does that count as a debugger?

    Thank you! :)

    To .Scott:

    Ah yes, I realise my mistake, but I feel that i=count should still remain because I have to concatenate str2[0] to str1[5], which for the latter is the '\0' character.

    Thank you! :)
     
  18. Oct 29, 2014 #17
    Trace for the first while loop:

    i 0 1 2 3 4 5
    count 1 2 3 4 5 X

    X-Terminates, since str1[5] is the NULL char.

    This is why I think i = count should still be there.

    However, for the 2nd while loop, I should have:

    Code (Text):

    while(s2[j]!= '\0')
          {
              s1[i]= s2[j];
              i++;
              j++;
          }
    s1[i] = '\0';
          return s1;
     
    I shall run the code tomorrow. Thanks to both for pointing out my mistakes and giving suggestions! :D
     
  19. Oct 29, 2014 #18

    Mark44

    Staff: Mentor

    I believe that the errors that vim notifies you of are syntax errors, errors you make in which you're using the language incorrectly. These are errors that the compiler can detect.

    The other type of error is a run-time error, which occurs when the program runs. The segmentation fault you're getting is a run-time error.
     
  20. Oct 29, 2014 #19
    I tried compiling my code erroneous code and I got this from gdb:

    May I know where do I see which line was at fault?

    Thanks! :)
     
  21. Oct 29, 2014 #20
    To Mark44: I see. :) Thanks!
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted