Why do I first have to strcpy() before strcat()?

Because stuff is uninitialized before the call to strcpy. After the declaration stuff isn't an empty string, it is uninitialized data.

strcat appends data to the end of a string - that is it finds the null terminator in the string and adds characters after that. An uninitialized string isn't gauranteed to have a null terminator so strcat is likely to crash.

If there were to intialize stuff as below you could perform the strcat's:

char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");

strcat will look for the null-terminator, interpret that as the end of the string, and append the new text there, overwriting the null-terminator in the process, and writing a new null-terminator at the end of the concatenation.

char stuff[100];  // 'stuff' is uninitialized

Where is the null terminator? stuff is uninitialized, so it might start with NUL, or it might not have NUL anywhere within it.

In C++, you can do this:

char stuff[100] = {};  // 'stuff' is initialized to all zeroes

Now you can do strcat, because the first character of 'stuff' is the null-terminator, so it will append to the right place.

In C, you still need to initialize 'stuff', which can be done a couple of ways:

char stuff[100]; // not initialized
stuff[0] = '\0'; // first character is now the null terminator,
                 // so 'stuff' is effectively ""
strcpy(stuff, "hi ");  // this initializes 'stuff' if it's not already.

In the first case, stuff contains garbage. strcat requires both the destination and the source to contain proper null-terminated strings.

strcat(stuff, "hi ");

will scan stuff for a terminating '\0' character, where it will start copying "hi ". If it doesn't find it, it will run off the end of the array, and arbitrarily bad things can happen (i.e., the behavior is undefined).

One way to avoid the problem is like this:

char stuff[100];
stuff[0] = '\0';      /* ensures stuff contains a valid string */
strcat(stuff, "hi ");
strcat(stuff, "there");

Or you can initialize stuff to an empty string:

char stuff[100] = "";

which will fill all 100 bytes of stuff with zeros (the increased clarity is probably worth any minor performance issue).

Tags:

C

C Strings