问题
I'm having difficulty with strncpy. I'm trying to split a string of 8 characters in two (the first 6 characters in one substring and then the remaining 2 characters in another). To illustrate the particular difficulty I have simplified my code to the following:
include stdio.h
include stdlib.h
include string.h
define MAXSIZE 100
struct word {
char string[8];
char sub1[2];
char sub2[6];
};
typedef struct word Word;
int main(void)
{
Word* p;
p=(Word*)malloc(MAXSIZE*sizeof(Word));
if (p==NULL) {
fprintf(stderr,"not enough memory");
return 0;
}
printf("Enter an 8-character string: \n");
scanf("%s",p->string);
strncpy(p->sub2,p->string,6);
strncpy(p->sub1,p->string,2);
printf("string=%s\n",p->string);
printf("sub1=%s\n",p->sub1);
printf("sub2=%s\n",p->sub2);
free(p);
return 0;
}
The user is prompted for an input. Suppose they input "12345678". Then the output of the program is:
string=1234567812123456
sub1=12123456
sub2=123456
The output I am expecting would be as follows:
string=12345678
sub1=12
sub2=123456
I don't understand how strncpy seems to be appending numbers to string... Obviously I don't understand strncpy well enough, but can anyone explain to me what's going on?
回答1:
C strings need to be terminated with a null character (0).
strncpy does not put a null terminator on the string for you. If you want a 2-character string, you need to allocate room for three characters, and set the final one to null.
Try this:
struct word {
char string[9];
char sub1[3];
char sub2[7];
};
// ...
strncpy(p->sub2,p->string,6);
p->sub2[6] = 0;
strncpy(p->sub1,p->string,2);
p->sub1[2] = 0;
// ...
Note that if the user inputs more characters than you've allocated room for, you'll end up with problems.
回答2:
You may find this part of the strncpy documentation useful:
The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null terminated.
You are printing strings that are not null-terminated. To fix this declare sub1
and sub2
with an extra char for the terminator:
char sub1[3];
char sub2[7];
And then null terminate after copying:
strncpy(p->sub2,p->string,6);
p->sub2[6] = '\0';
strncpy(p->sub1,p->string,2);
p->sub1[2] = '\0';
回答3:
The strncpy() function copies at most n characters from s2 into s1. If s2 is less than n characters long, the remainder of s1 is filled with `\0' characters. Otherwise, s1 is not terminated.
So given your string is longer, the strings are not zero terminated. When you print them, prinf is printing the characters you copied, but then carrying on printing whatever is there until it hits a NUL
Althoug scanf does NUL terminate its string, you've not allocated enough space. String
in your stuct needs to be 9 characters long - 8 for the characters (12345678) and one more for the NUL. Right now the NUL is going in the first character of str1 - which you then overwrite with the strncpy
来源:https://stackoverflow.com/questions/4483362/strncpy-question-c-language