Dunc
Dunc

Reputation: 8058

strncpy introduces funny character

When I run some code on my machine then it behaves as I expect it to.

When I run it on a colleagues it misbehaves. This is what happens.

I have a string with a value of:

croc_data_0001.idx

when I do a strncpy on the string providing 18 as the length my copied string has a value of:

croc_data_0001.idx♂

If I do the following

myCopiedString[18]='\0';
puts (myCopiedString);

Then the value of the copied string is:

croc_data_0001.idx

What could be causing this problem and why does it get resolved by setting the last char to \0?

Upvotes: 2

Views: 2980

Answers (5)

Mr Lister
Mr Lister

Reputation: 46589

strncpy does not always add a \0. See http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

So either clear out your destination buffer beforehand, or always add the \0 yourself, or use strcpy.

If the question is: "why does uninitialised memory on my machine have different content than on another machine", well, one can only guess.

Edit changed wording somewhat; see comment.

Upvotes: 0

Lundin
Lundin

Reputation: 214385

I think the C standard describes this function in a clearer manner than the links others have posted.

ISO 9899:2011

7.24.2.4 The strncpy function

char *strncpy (char * restrict s1,
               const char * restrict s2,
               size_t n);

The strncpy function copies not more than n characters (characters that follow a null character are not copied) from the array pointed to by s2 to the array pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.

If the array pointed to by s2 is a string that is shorter than n characters, null characters are appended to the copy in the array pointed to by s1, until n characters in all have been written.

Upvotes: 1

glglgl
glglgl

Reputation: 91109

strncpy does not want the size of the string to be copied, but the size of the target buffer.

In your case, the target buffer is 1 too short, disabling strncpy to zero-terminate the string. So everything that is behind the string resp. position 18 and is non-zero will be treated as belonging to the string.

Normally, functions taking a buffer size are called with exactly that, i. e.

char dest[50];
strncpy(dest, "croc_data_0001.idx", sizeof dest);

With this and an additional

dest[sizeof dest - 1] = '\0';

the string will always be 0-terminated.

Upvotes: 1

Amey
Amey

Reputation: 55

how much space have been alloted to myCopiedString variable? if its more than the length of the source string, then make sure you use bzero to clear out the destination variable.

Upvotes: 0

Alexander Pavlov
Alexander Pavlov

Reputation: 32296

According to http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

char * strncpy ( char * destination, const char * source, size_t num );
Copy characters from string

Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it. No null-character is implicitly appended to the end of destination, so destination will only be null-terminated if the length of the C string in source is less than num.

Thus, you need to manually terminate your destination with '\0'.

Upvotes: 5

Related Questions