问题
I am reading this document, it says:
char *strncpy(char *destination, const char *source, size_t num);
Copy characters from string Copies the first
num
characters ofsource
todestination
. If the end of thesource
C string (which is signaled by a null-character) is found beforenum
characters have been copied,destination
is padded with zeros until a total ofnum
characters have been written to it.No null-character is implicitly appended at the end of destination if source is longer than
num
. Thus, in this case,destination
shall not be considered a null terminated C string (reading it as such would overflow).
destination
andsource
shall not overlap (seememmove
for a safer alternative when overlapping).
But I am confused by this statement:
in this case, destination shall not be considered a null terminated C string (reading it as such would overflow)
Since if num > strlen(source)
, it will pad with '\0'
at the end, '\0'
is actually a null (terminating) character in a string, why it shall not be considered a null-terminated C string?
I have written below code to verify:
char from[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
char to[1024];
for (int i = 0; i < 1024; i++) {
to[i] = 'e';
}
strncpy(to, from, 1024);
printf("from %s\n", from);
It works fine with below output:
from hello
to hello
回答1:
It's talking about the case when strlen(source)
> num
. It will only copy num
chars, none of which is a NUL and it will not add a NUL.
回答2:
strncpy(dst, src, len)
only adds a null terminator to dst
if there is a null terminator in src
within the first len
bytes. Your code might seem to work, because there might or might not be a null character after the array to[]
. A better test is:
char source[] = "source";
char dest[] = "destination";
strncpy(dest, source, 6);
printf("%s\n", dest);
The result should be:
sourceation
If you write strncpy(dest, source, 7)
instead, then the output is just the word source
.
回答3:
The semantics of strncpy()
, even when precisely explained as they are in the C++ reference above, are widely misunderstood. The behavior of this function is counterintuitive and error prone.
To avoid problems when using it or further down the development process, when the maintainer will misread the code and add more subtile bugs, there is a simple solution: NEVER EVER USE THIS FUNCTION.
You can read further details about this in this article by Bruce Dawson.
To answer your question: if the source string is longer than the size passed as a third argument (usually corresponding to the size of the destination buffer), the function will copy size characters to the destination and no null byte will be present among these. Calling strlen(destination);
will then invoke undefined behavior because it will attempt to read beyond the end of the array until it finds a null terminator. This specific behavior is what makes strncpy
so error prone.
来源:https://stackoverflow.com/questions/41045214/c-strncpy-null-terminated-or-not