2

自分のマシンでコードを実行すると、期待どおりに動作します。

同僚に実行すると、誤動作します。これが起こることです。

次の値の文字列があります:

croc_data_0001.idx

strncpyコピーした文字列の長さが18である文字列に対して、を実行すると、次の値になります。

croc_data_0001.idx♂</p>

私が次のことをすると

myCopiedString[18]='\0';
puts (myCopiedString);

コピーされた文字列の値は次のとおりです。

croc_data_0001.idx

この問題の原因は何でしょうか。また、最後の文字をに設定することで問題が解決するのはなぜ\0ですか。

4

5 に答える 5

5

http://www.cplusplus.com/reference/clibrary/cstring/strncpy/によると

char * strncpy ( char * destination, const char * source, size_t num );
Copy characters from string

ソースの最初のnum文字を宛先にコピーします。num文字がコピーされる前にソースC文字列(ヌル文字で示される)の終わりが見つかった場合、合計num文字が書き込まれるまで、宛先にゼロが埋め込まれます。宛先の末尾にヌル文字が暗黙的に追加されることはないため、宛先の宛先は、ソース内のC文字列の長さがnum未満の場合にのみヌルで終了します。

したがって、宛先を「\0」で手動で終了する必要があります。

于 2012-02-27T12:14:21.800 に答える
1

strncpy文字列のサイズではなく、ターゲットバッファのサイズをコピーする必要があります。

あなたの場合、ターゲットバッファが1短すぎるためstrncpy、文字列をゼロで終了できません。したがって、文字列応答の背後にあるすべてのもの。位置18でゼロ以外の場合は、文字列に属するものとして扱われます。

通常、バッファサイズをとる関数は、まさにそれで呼び出されます。

char dest[50];
strncpy(dest, "croc_data_0001.idx", sizeof dest);

これと追加で

dest[sizeof dest - 1] = '\0';

文字列は常に0で終了します。

于 2012-02-27T12:26:03.787 に答える
1

C規格は、他の人が投稿したリンクよりも明確にこの機能を説明していると思います。

ISO 9899:2011

7.24.2.4strncpy関数

char *strncpy (char * restrict s1,
               const char * restrict s2,
               size_t n);

strncpy関数は、s2が指す配列からs1が指す配列にn文字以下をコピーします(ヌル文字に続く文字はコピーされません)。オーバーラップするオブジェクト間でコピーが行われる場合、動作は定義されていません。

s2が指す配列がn文字より短い文字列である場合、全部でn文字が書き込まれるまで、s1が指す配列のコピーにヌル文字が追加されます。

于 2012-02-27T12:32:23.907 に答える
0

strncpy常に追加されるわけではありません。http://www.cplusplus.com/reference/clibrary/cstring/strncpy/\0.を参照してください。

したがって、事前に宛先バッファをクリアするか、常に\0自分自身を追加するか、を使用してくださいstrcpy

質問が「私のマシンの初期化されていないメモリの内容が別のマシンと異なるのはなぜですか」という場合、推測することしかできません。

変更された文言をいくらか編集します。コメントを参照してください。

于 2012-02-27T12:13:41.467 に答える
0

myCopiedString変数にどのくらいのスペースが割り当てられていますか?ソース文字列の長さを超える場合は、必ずbzeroを使用して宛先変数をクリアしてください。

于 2012-02-27T12:20:26.173 に答える