2010-12-19 11 views
0

私はstrncpyで問題があります。私は8文字の文字列を2つに分割しようとしています(最初の6文字を1つの部分文字列に、残りの2文字を別の文字列に分割します)。ユーザーが入力を求めるプロンプトが表示されstrncpy質問(C言語)

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を理解していないが、誰も私に何が起こっていることを説明することができますか?

+0

あなたは確かにそのmallocキャストを取り除きたいです! http://c-faq.com/malloc/mallocnocast.html – user502515

答えて

5

C文字列はヌル文字(0)で終わる必要があります。

strncpyは、文字列にヌルターミネーターを入れません。 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; 
// ... 

注:

はこれを試してみてください。

+0

他のポスターに感謝します。私は今起こっていたことを理解し、それに応じて自分のコードを修正することができました。とてもありがたい! – Andrew

+0

問題ありません..... – sje397

2

あなたは便利なstrncpyドキュメントのこの部分を見つけることがあります。

はstrncpy()関数はせいぜいことを除いて、類似したn個のSRC のバイトがコピーされます。警告:srcの最初のnバイトのうち、 の間にヌルバイトがない場合、destに配置された文字列はnullで終了しません。

ヌル終了していない文字列を印刷しています。ターミネータのための余分な文字で、この宣言sub1sub2を修正するには:

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'; 
+0

それだけでは不十分です。また、コピーした後にヌルターミネータを置く必要があります。 –

+1

strncpy()関数は、memcpy()と同様に、常に 'n'バイトを書き込み先に書き込みます。 strncpy()とmemcpy()の唯一の違いは、最初のゼロバイトに続くバイトは、ソースからコピーされるのではなく、ゼロとして書き込まれることです。 – supercat

1

はstrncpy()関数をコピー最も n文字でからs2をs1に入れる。 s2がn文字未満の場合、s1の残りは `\ 0 '文字で で埋められます。それ以外の場合、s1は終了しません。

文字列が長ければ、文字列はゼロ終了しません。あなたがそれらを印刷するとき、prinfはあなたがコピーした文字を印刷していますが、NULに当たるまで印刷し続けます。

Althoug scanfはNULで文字列を終了します。あなたのスタウトのStringは、の長さの文字(12345678)の場合は8、NULの場合は1つ必要です。今すぐNULはstr1の最初の文字に入っています。strncpyで上書きします。

+0

s1_の_remainderは、私の経験(MinGW)では常に変更されません。おそらく、他の環境では\ 0文字で_埋められています。 – Salvador