Reputation: 2973
#include <iostream>
using namespace std
#include <string.h>
int main(){
char token[] = "some random string";
char c[23];
strcpy( c, token);
strncpy(c, token, 5);
c[strlen(c)] = '\0';
cout<<c;
return 0 ;
}
My output is: some random string
. But I expect it to be: some
. Can anyone please explain why it is behaving like this?
Upvotes: 0
Views: 5964
Reputation: 1122
As others have mentioned, unlike snprintf
to sprintf
, strncpy
is not a safer version of strcpy
. It merely ensures that "exactly N characters are copied to destination (use NUL if source string is shorter than N)". (man page)
But I think you've already noticed that by the line
c[strlen(c)] = '\0';
It meant to ensure the null termination of c
. But it is actually pointless since strlen
uses NUL to determine the length of c
. So this line barely means "find NUL and write NUL to that location".
The importance of strncpy
is to copy a certian part of string. It is not a fix to strcpy
, and existed before the introduction of snprintf
functions.
Upvotes: 0
Reputation: 9929
I think your output should be "some random string", because your two lines of code do nothing, see the comment.
int main(){
char token[] = "some random string";
char c[23];
strcpy( c, token);
strncpy(c, token, 5); // Does nothing
c[strlen(c)] = '\0'; // Does nothing
cout<<c;
return 0 ;
}
If you want to output "some", you could do this:
strncpy(c, token, 5);
c[5] = '\0';
strncpy() doesn't automatically add trailing '\0' to dest string. If the source string length is bigger than len (3rd argument of strncpy), then len characters copied to dest without trailing '\0'. So you have to give a trailing '\0' explicitly by code.
Upvotes: 4
Reputation: 400642
It's working just fine—bear in mind that strncpy
does not necessarily null-terminate the string. When you do this:
strncpy(c, token, 5);
It copies the first 5 bytes of token
into c
but does not null-terminate the result. Furthermore, this line is useless:
c[strlen(c)] = '\0';
strlen(c)
looks for an existing null terminator, and as soon as you find one, you overwrite it with another null terminator, which is pointless.
In new code, strncpy
should seldom, if ever be used. Its intended use (fixed-length buffers which are not necessarily null-terminated) have long been obseleted. Prefer instead a function like strlcpy
(note: strlcpy
is not standard; it's only available in BSD-like systems).
Or, if you're coding in C++ instead of pure C, just use std::string
and avoid tricky issues like this altogether.
Upvotes: 6