strncpy question (C language)

为君一笑 提交于 2019-12-25 04:44:22

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!