0

我在使用 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 的理解不够好,但谁能向我解释发生了什么?

4

3 回答 3

6

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

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

尝试这个:

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

请注意,如果用户输入的字符多于您分配的空间,您最终会遇到问题。

于 2010-12-19T14:30:21.540 回答
2

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

strncpy() 函数类似,只是最多复制 n 个字节的 src。警告:如果 src 的前 n 个字节中没有空字节,则放在 dest 中的字符串不会以空值结尾。

您正在打印非空终止的字符串。要修复此声明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';
于 2010-12-19T14:31:44.120 回答
1

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

因此,鉴于您的字符串较长,字符串不会以零结尾。当您打印它们时,prinf 正在打印您复制的字符,然后继续打印那里的任何内容,直到它达到 NUL

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

于 2010-12-19T14:35:53.817 回答