strncpy问题(C语言)

时间:2010-12-19 14:28:54

标签: c string strncpy

我对strncpy有困难。我试图将一个包含8个字符的字符串分成两个字符串(一个子字符串中的前6个字符,然后是另一个字符串中的剩余2个字符)。为了说明特殊的困难,我将代码简化为以下内容:

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;  
}

提示用户输入。假设他们输入“12345678”。然后程序的输出是:

string=1234567812123456  
sub1=12123456  
sub2=123456

我期待的输出如下:

string=12345678  
sub1=12  
sub2=123456

我不明白strncpy似乎是如何将数字附加到字符串上...显然我不太了解strncpy,但有人可以向我解释发生了什么事吗?

3 个答案:

答案 0 :(得分:6)

C字符串需要以空字符(0)终止。

strncpy没有为你在字符串上放置一个null终结符。如果你想要一个2个字符的字符串,你需要为三个字符分配空间,并将最后一个字符设置为空。

试试这个:

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;
// ...

请注意,如果用户输入的字符多于您为其分配的空间,则最终会出现问题。

答案 1 :(得分:2)

您可能会发现strncpy文档的这一部分很有用:

  

strncpy()函数类似,除了src的最多n个字节       被复制。警告:如果前n个字节中没有空字节       对于src,放在dest中的字符串不会以null结尾。

您正在打印非空终止字符串。要解决此问题,请为sub1sub2声明终结符的额外字符:

char sub1[3];
char sub2[7];

然后在复制后null终止:

strncpy(p->sub2,p->string,6);  
p->sub2[6] = '\0';
strncpy(p->sub1,p->string,2); 
p->sub1[2] = '\0';

答案 2 :(得分:1)

  

strncpy()函数最多复制   n从s2到s1的字符。如果   s2小于n个字符长,s1的剩余部分被填充   用'\ 0'字符。否则,s1不会被终止。

因此,如果您的字符串更长,则字符串不会以零结尾。当你打印它们时,prinf正在打印你复制的字符,然后继续打印那里的东西,直到它打到NUL

Althoug scanf确实NUL终止了它的字符串,你没有分配足够的空间。您的结果中的String需要 9 个字符 - 字符为8(12345678),NUL为一个。现在,NUL进入str1的第一个字符 - 然后用strncpy覆盖