C++: strcpy Function copies null?

Viewed 65190

While using string manipulation functions specificaly strcpy I did this small program.

char s1[8]="Hellopo";
char s2[4]="sup";
strcpy(s1,s2);
cout<<s1<<endl;

When I printed out s1 It actually just printed out "sup". I expected it to print "suplopo".

Then I did this:

cout<<s1+4 << endl;

It printed out "opo";

And The output of this: cout<<s1+3<<endl; was nothing

So after thinking a bit about it.

I came to this conclusion. Since C++ stops outputing the string once it reaches the null terminator. Therefore the null must have been copied in the strcpy function. Resulting in this string:

s - u - p - \0 - o - p - o -\0;

Please tell me if this is correct or not. And if im not please correct me.

And if you have any more info to provide please do.

7 Answers

Your reasoning regarding the copying of the terminating character is correct. The C++ standard (which is the definitive specification for the language) defers to C on this matter (for example, C++14 defers to C99, and C++17 defers to C11).

The C11 standard has this to say about strcpy:

7.24.2.3 The strcpy function

Synopsis:

#include <string.h>
char *strcpy(char * restrict s1, const char * restrict s2);

Description:

The strcpy function copies the string pointed to by s2 (including the terminating null character) into the array pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.

Returns:

The strcpy function returns the value of s1.

If you just wanted to replace the first three characters of your string, you can use memcpy() to copy a specific number of bytes:

memcpy(s1, s2, strlen(s2));

Keep in mind that this will just copy those bytes and nothing more. If s1 isn't already a string of at least the length of s2, it's unlikely to end well :-)


And just keep one thing in mind re your comment "... resulting in this string: sup\0opo\0".

That is not a string. A string in C (and a legacy string in C++) is defined as a series of characters up to and including the first \0 terminator.

You may well have a series of characters up to the original (now second) \0 but the string is actually shorter than that. This may seem a little pedantic but it's important to understand the definitions.

Yes, you are correct in your reasoning and if you would have explicitly typecast-ed the 4th character 's1[3]' as integer like this:

cout<<(int)s1[3];

You would have gotten "0" as the output which is the ASCII value of NULL character.

Related