0

strncpy に問題があります。8 文字の文字列を 2 つに分割しようとしています (最初の 6 文字を 1 つの部分文字列に、残りの 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文字列に null ターミネータを配置しません。2 文字の文字列が必要な場合は、3 文字分のスペースを割り当て、最後の文字を 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() 関数も同様ですが、src の最大 n バイトがコピーされる点が異なります。警告: src の最初の n バイトに null バイトがない場合、dest に配置された文字列は null で終了しません。

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';
于 2010-12-19T14:31:44.120 に答える
1

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

于 2010-12-19T14:35:53.817 に答える