2011-08-10 3 views
2

私は文字列をcで学習しています。私はcode :: blocksをコンパイラとして使用していますが、それだけではありません。したがって、以下のコードの問題は、string2の出力が、格納された5文字+ string1の出力であることです。私はあなたを紹介します:Cで文字列をコピーする

#include <stdio.h> 
#include <string.h>   /* make strncpy() available */ 

int main() 
{ 
char string1[]= "To be or not to be?"; 
char string2[6]; 

/* copy first 5 characters in string1 to string2 */ 
strncpy (string2, string1, 5); 

printf("1st string: %s\n", string1); 
printf("2nd string: %s\n", string2); 
return 0; 
} 

出力は次のとおりです。

1st string contains: To be or not to be? 
2nd string contains: To be To be or not to be? 

あなたは私に言わせれば、それが5つの文字よりも多くの...

答えて

3

あなたは「\ 0」で文字列2を終了するので、printfのオーバーランされていません。完全を期すために

は、ここにコードがあります。してみてください:

memset(string2,0,6); 

文字列2を使用する前にしてください。 か、あなたはstrncpyをした後、5文字をコピーしている知っているので:

string2[5] ='\0'; 

をので、あなたが適切に正しく文字列を終了します。

あなたがコピーした文字数の後ろに '\ 0'を置く必要があることに注意してください。そうしないと、文字列の途中でもガベージが表示されます。

+0

ありがとうございます。私が思う第二の選択肢は私の外ですが、私は最初のオプションをプログラムで適切に機能させることができました。とても有難い。 :)かわいい赤ちゃん、btw。 –

+0

@Michael 2番目のオプションが優れています。基本的に文字列の最後の重要な文字の後に '\ 0'を追加します。ありがとう;) –

10

strncpy manページから:

ヌル文字は暗黙的に宛先の末尾に追加されないため、宛先はCの長さソースの文字列がnumより小さい。

元の文字列の長さが5より長いため、NULLは追加されません。他の人が指摘したように

は、それにいくつかの安全性を追加します。

char * string2 = malloc(123); //sizeof(string2) == sizeof(void *) and not 123 

そして、上記のコードは失敗します:string2malloc()を介して取得された場合に

strncpy (string2, string1, sizeof(string2)); 
string2[sizeof(string2)-1] = '\0'; 

注意を。 http://ideone.com/eP4vd

+0

が故に、strncpyを、その危険なを使用していけない:

は、ここで一つの解決策です。 – Tom

+0

OPをクリアするには、 'string2 [5] = '\ 0';'を追加して、文字列を正しく終了させる必要があります。 nullがなければ、 'printf'は文字列の終了を知らないので、見つかるまでメモリを読み続ける。 – dcpomero

+2

@Tom、人々が危険であると言うCのほとんどのものは、彼らが何をやっているのか分からない人にとって危険です。彼らはBASICに固執すべきです:-)無制限の '%s'フォーマット指定子を持つ' gets'や 'scanf'のような例外がありますが、それらを使う方法を知っている人にとっては大多数が問題ありません。 – paxdiablo

0

string2には\0が含まれていないため、この文字列は終了しません。あなたがそれを印刷しているときには、範囲外に出て、見つかったものは何でも\0が見つかるまで印刷します。

strncpyの後に、正しく終端された文字列を使用する場合は、手動で\0を挿入する必要があります。

1

基本的には両方の文字列は、メモリ内の隣同士にスタック上にあり、ヌルターミネータはstring2の後に存在しないので、それはそれはstring1 + string2 +ランダム1つのバイト値(string2[5])から「であるために」を印刷します印刷していますとき、ヌルバイトを打つ前に(「するべきかどうか」)。

ランダムな1バイト値が0だった場合、それは停止します。あなたはあなたが期待するプリントを得るでしょう。

0

strncpyには制限があります。上記を参照してください。 が

sprintf(string2, "%.*s", sizeof(string2)-1, string1); 
0

strncpy()などのsprintfのを見て、その名前にもかかわらず、単にstrcpy()のより安全な境界が指定したバージョンではありません。それはあいまいな意味を持つあいまいな関数なので、C標準ライブラリに含めてはならないと主張します。一方、であり、より安全な範囲指定バージョンstrcat()である。

char string1[]= "To be or not to be?"; 
char string2[6]; 

string2[0] = '\0'; 
strncat (string2, string1, 5); 
関連する問題