Implementing strcat without string.h in C

In summary: T.TIn summary, The conversation was about implementing the function my_strcat(s1,s2) to append a copy of string s2 to the end of string s1. The conversation also discussed the use of pointers and a while loop to properly concatenate the strings. There were some errors pointed out in the code and suggestions for improvement were given. Finally, it was discovered that the variables s1 and s2 were not properly initialized, leading to a segmentation fault.
  • #1
galaxy_twirl
137
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:
#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.
 
Physics news on Phys.org
  • #2
There are many things wrong with your code. I'll point out a few:
galaxy_twirl said:
Code:
      type_berry = my_strcat(s1, s2);
What is the value of s1 and s2 at this point?

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

  i = count;
Why do you have both count and i as variables?

galaxy_twirl said:
Code:
      while(s2[j]!= '\0')
      {
          s1[i]= s2[j];
          i++;
          j++;
      }

      return s1;
  }
Do you guarantee that string s1 will end properly?
 
  • #3
Hi DrClaude. Oh dear. Hmm.. I need to think about my answers to the other questions, but I had:
Code:
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.
 
  • #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).. :(
 
  • #5
I tried to put:
Code:
while(s2[j]!= '\0' && s1[i] != '\0'){
{
    s1[i]= s2[j];
    i++;
    j++;
}

  return s1;
}

but I got a seg. fault again. T.T
 
  • #6
I'll ask again. When the program reaches the line
C:
type_berry = my_strcat(s1, s2);
what are s1 and s2 pointing to?

galaxy_twirl said:
I had:
Code:
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.
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.
 
  • #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? ><
 
  • #8
galaxy_twirl said:
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.
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.
galaxy_twirl said:
C:
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);
 
  • #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.
 
  • #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:
#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;
}
 
  • #11
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:
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:
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:
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.
 
  • #12
galaxy_twirl said:
Code:
   while(s2[j]!= '\0'&& s1[i]!= '\0')
   {
          s1[i]= s2[j];
          count++;
          j++;
   }
   s1[i] = '\0';
   return s1;
}
This part is broken.
 
  • #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
 
  • #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.
 
  • #15
galaxy_twirl said:
But after staring at it for some time, I still can't write a correct code. May I have some hints please?
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.
 
  • #16
To DrClaude:

the resulting executable ends with a segmentation fault, that means you didn't test it before posting.
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 realize 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! :)
 
  • #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:
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
 
  • #18
galaxy_twirl said:
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.
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.
 
  • #19
DrClaude said:
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.

I tried compiling my code erroneous code and I got this from gdb:

warning: Temporarily disabling breakpoints for unloaded shared library "/usr/lib/ld.so.1"

Program received signal SIGSEGV, Segmentation fault.
0xff242d18 in strlen () from /usr/lib/libc.so.1

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

Thanks! :)
 
  • #20
To Mark44: I see. :) Thanks!
 
  • #21
Code:
while(s2[j]!= '\0')
      {
          s1[i]= s2[j];
          i++;
          j++;
      }
s1[i] = '\0';
      return s1;

Hmm. I still have a segmentation fault when I ran my program. But this is weird, because when I trace the program, after the first while loop, the loop should have terminated, then, the above while loop starts, and it should end when s2 hits a NULL char, so logically, I shouldn't be exceeding the memory space allocated to me which produces a seg. fault.

May I know if my thought processes are wrong?

Thank you. :)
 
  • #22
galaxy_twirl said:
Code:
while(s2[j]!= '\0')
      {
          s1[i]= s2[j];
          i++;
          j++;
      }
s1[i] = '\0';
      return s1;

Hmm. I still have a segmentation fault when I ran my program. But this is weird, because when I trace the program, after the first while loop, the loop should have terminated, then, the above while loop starts, and it should end when s2 hits a NULL char, so logically, I shouldn't be exceeding the memory space allocated to me which produces a seg. fault.
When you say, "after the first while loop, the loop should have terminated," did it terminate? What you wrote suggests that you were expecting it to terminate, but for some reason it didn't.

Use the debugger to single-step through your code. When you hit the seg fault, note which line caused it, and the values of the relevant variables.
 
  • #23
galaxy_twirl said:
May I know where do I see which line was at fault?
When the error happens in the code your wrote, gdb will tell you where immediately. The problem you are having now only creeps up in a system function, namely strlen. To know what your code was doing, use the command "where" in gdb after the segmentation fault:
Code:
(gdb) where
#0  0x00007fff8a434c00 in strlen ()
#1  0x00007fff8a4405fc in __vfprintf ()
#2  0x00007fff8a4818ab in vfprintf_l ()
#3  0x00007fff8a4af007 in printf ()
#4  0x0000000100000dec in main () at my_strcat.c:18
so the error is in the printf on line 18.
 
  • #24
I know what my mistake was. I printed a string with a * instead of its address, which led to the segmentation fault.

Thanks DrClaude for your tip on using gdb and Mark44 for your guidance in debugging my code. :)
 
  • #25
Yes
galaxy_twirl said:
I know what my mistake was. I printed a string with a * instead of its address, which led to the segmentation fault.
Yes.
C:
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);  //  << -- This line
      return 0;
  }
I saw this before and thought it might be causing you trouble. What's happening is that the %s conversion specifier in printf is expecting the address of the first character of a string. *type_berry is the character 'g', but because of the %s, the value of the character (which is a number) is being interpreted as an address. That's your seg fault.
 
Last edited:
  • Like
Likes galaxy_twirl

Related to Implementing strcat without string.h in C

1. How do I implement strcat without using the string.h library in C?

To implement strcat without using the string.h library in C, you can use a loop to iterate through the characters of the two strings and concatenate them into a new string. You will need to allocate enough memory for the new string and make sure to add a null terminator at the end.

2. Why would I need to implement strcat without string.h in C?

There may be situations where the string.h library is not available or cannot be used, such as in embedded systems or when working with low-level programming. In these cases, implementing strcat without string.h can be a useful skill.

3. Can I use the strcat function without the string.h library in C?

No, the strcat function is part of the string.h library and cannot be used without it. However, you can create your own strcat function by implementing the necessary steps to concatenate two strings without using the string.h library.

4. Are there any downsides to implementing strcat without string.h in C?

One potential downside is that implementing strcat without string.h may be more time-consuming and error-prone compared to using the built-in function. Additionally, it may not be as efficient in terms of memory usage or performance.

5. Can I implement other string functions without string.h in C?

Yes, you can implement other string functions such as strcpy, strlen, and strcmp without using the string.h library. These functions will also require a similar approach of iterating through the characters of the string and performing the necessary operations.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
2
Views
957
  • Engineering and Comp Sci Homework Help
Replies
21
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
958
  • Engineering and Comp Sci Homework Help
Replies
14
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
12
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
Back
Top