strncpy doesn’t seem to be putting a null terminator at the end of the buffer it is copying too. For example:
char buf1[16]
char buf2[8];
strcpy(buf1,"123456789");
strncpy(buf2,buf1,4);
printf("%s",buf2); // outputs 1234andsomegarbage
// I'm having to manually put in this null
strcpy(&buf2[4], "");
printf("%s",buf2); // now outputs 1234
I’ve worked around the problem by manually inserting the null, but it seems that the strncpy should do that (and its documentation suggest that it does).
Any thoughts?
Incidentally, a better way to stick in that null terminator than the method in my code snippet above:
buf2[4] = '\0';
strcpy copies up to (and including) the null terminator in a string.
strncpy copies ‘n’ characters and stops. If a null terminator is encountered in the process, then it is copied and the copy process stops.
Since string buf1 is longer than four characters, no null terminator was placed in buf2.
Well, that’s certainly the behavior, but it isn’t how the function is documented (unless I’m misunderstanding the documentation). From the “Dynamic C Function Reference”:
Copies a given number of characters from one string to another and padding with null characters or truncating as necessary.
The part about padding with null characters led me to believe that a null terminator would be added to the destination buffer at the end of the copied characters. Am a wrong in my reading of what the documentation says?
I think you misunderstood the use of or in the documentation. This matches my information earlier.
-
If the source string is shorter than ‘n’, then the remaining characters are padded with nulls in the destination string. (Padding means to fill in when you come up short.)
-
If the source string is longer than ‘n’, then only ‘n’ characters are copied … period. Truncation occurs because you didn’t come up short. This is the case in your example.
Ah, that makes sense… I should have paid more attention to the word “padding.”
Quoting from the book “Embedded Systems Design using the Rabbit 3000 Microprocessor : Interfacing, Networking, and Application Development”
By Kamal Hyder & Bob Perrin
Page 99
When using strncpy() […] the programmer must take into account what happens when the string is too large for the buffer. In this case the destination buffer will not be NULL terminated. For example
#define BUFFER_SIZE 10
char buffer[BUFFER_SIZE];
strncpy(buffer, "this string is too long", BUFFER_SIZE);
The source string is longer than 10 bytes. After the strncpy(), buffer will contain the first 10 chars of the long string but it will not be NULL terminated. Therefore, if we later attempt to print the string, it will output the string followed by [b]garbage characters[/b].
To prevent this, we can always explicitly NULL-terminate the string after the strncpy() like this
buffer[BUFFER_SIZE - 1] = '\0';
I hope that quoting this entry from the book (which is a must for Rabbit 3000 developers) is not against the forum rules.
Besides, one can find the above information by going to books.google.com, finding the book and then searching within the book for “strncpy()”.
RG