String Catenation in C

Hey guys, so I've been working my way through the original C programming book (K&R) and it's been surprisingly mind-blowing for someone who started on Python and Java a few years back.

I've gotten to the pointers section of the book and one of the tasks is to modify the strcat (string catenation) function to append one char array on the end of another array.

The solution code is as follows:

 <code>

#include <stdio.h>

//void cstrcat(char [], char []);
void cstrcat(char *s, char *t);

int main()
{
char s[100] = "Hello World.";
char t[] = " How are you?";

printf("%s\n", s);

cstrcat(s, t);
printf("%s\n", s);

return 0;
}

// strcat: concatenate t to end of s; s must be big enough
//char [] and char * are equivalent; preferring char * to
//explicitly state it is a pointer.

void cstrcat(char *s, char *t)
{
while (*s != '\0') {
s++;
}
while ((*s = *t) != '\0') {
s++;
t++;
}
}
</code> 

 However I don't completely understand the strcat function (named cstrcat here for conflict reasons with the standard library).

I understand that you create an array, and pass it a pointer (which is the variable s in main, acting as &s[0]), but the process somewhat confuses me. Strcat steps through s[] until it reaches '\0' and then replaces '\0' with the first character in, t, and continues to step through t, adding to s as it does so. I just don't understand  why I am able to write the function like this:
<code>

void cstrcat(char *s, char *t)
{
while (*s != '\0') {
s++;
}
while ((*s++ = *t++) != '\0');
}
</code> 

 but not like my initial attempt:
<code>

void cstrcat(char *s, char *t)
{
while (*s++ != '\0');
while ((*s++ = *t++) != '\0');
}
</code> 

 Can anyone shed any light on why this is the case? In the last attempt above, the final string is still "Hello World." and the catenation fails to append t onto s.

Any ideas would be great. Thanks.

The first version doesn't move the pointer forward after identifying the null character, so when t gets copied the first character overwrites the null character.

In the second version, the pointer gets incremented every time, so in memory you get something like this:

{ 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '.', '\0', ' ', 'H', 'o', 'w', ' ', 'a', 'r', 'e', ' ', 'y', 'o', 'u', '?' }

Notice that the second null character could end up being out of the bounds of the array if the memory was allocated to exactly fit the properly combined strings. It is still being copied though, so it could potentially be overwriting something else in memory.

 

Dude, perfect! Thank you so much for taking the time to explain this to me, your demonstration is perfect.

I couldn't understand why it was the same as the 2nd while loop but not completing the operation in the same way. I forget C terminates the printf() function with '\0' so at least it was still copying the other string.

And don't worry, I was making the original array large enough. Thanks again.