20

多くのコードサンプルでは、​​通常、'\0'次のような新しいchar配列を作成した後に使用します。

string s = "JustAString";
char* array = new char[s.size() + 1];
strncpy(array, s.c_str(), s.size());
array[s.size()] = '\0';

なぜ'\0'ここで使用する必要がありますか?

4

5 に答える 5

45

質問のタイトルはC文字列を参照しています。C ++オブジェクトは、標準のCstd::string文字列とは異なる方法で処理されます。C文字列を使用する場合は重要です。ここでこの用語を使用するときは、標準のC文字列を指します。\0string

\0Cでは文字列ターミネータとして機能します。これはヌル文字またはNULとして知られています。これは、文字列を処理するコード(標準ライブラリだけでなく、独自のコード)に信号を送ります。ここで、文字列の終わりがあります。良い例はstrlen、文字列の長さを返すことです。

次のコマンドで定数文字列を宣言する場合:

const char *str = "JustAString";

その後、\0が自動的に追加されます。配列の例のように非定数の文字列を管理する場合は、自分で処理する必要がある場合があります。例で使用されているstrncpyのドキュメントは、良い例です。文字列全体がコピーされる前に指定された長さに達した場合を除いstrncpyて、null終了文字をコピーします。したがって、ヌルターミネータの冗長な割り当てと組み合わされていることがよくあります。そして、このケースの処理を怠ることから生じる潜在的な問題に対処するように設計されました。strncpystrlcpystrcpy_s

あなたの特定の例でarray[s.size()] = '\0';は、はそのような冗長性の1つです。arrayはサイズがs.size() + 1で、文字strncpyをコピーしs.size()ているため、関数は。を追加し\0ます。

標準のC文字列ユーティリティのドキュメントには、このようなnullターミネータを含めるように注意する必要がある場合が示されています。ただし、ドキュメントを注意深く読んでstrncpyください。詳細と同様に、見落とされがちで、バッファオーバーフローが発生する可能性があります。

于 2012-06-08T04:23:13.190 に答える
15

C ++の文字列が通常で終了するのはなぜ'\0'ですか?

C++文字列とC文字列は同じではないことに注意してください。
C ++では、文字列はstd :: stringを参照します。これは、テンプレートクラスであり、文字列を処理するための多くの直感的な関数を提供します。
C ++ std :: stringは終了しません\0が、クラスは、基になる文字列データを\0終了したcスタイルの文字列としてフェッチする関数を提供することに注意してください。

Cでは、文字列は文字のコレクションです。このコレクションは通常、で終わり\0ます。
のような特殊文字が使用されていない限り、\0文字列がいつ終了するかを知る方法はありません。
これは、文字列ヌルターミネータとしても適切に知られています。

もちろん、文字列の長さを追跡するための簿記の他の方法もありますが、特殊文字を使用することには2つの直接的な利点があります。

  • より直感的で
  • 追加のオーバーヘッドはありません

\0ほとんどの標準Cライブラリ関数は、文字列が\0終了していることを前提として文字列を操作するため、これが必要であることに注意してください。
例:
使用中、終了printf()していない文字列がある場合は、が検出されるまで文字を書き込み続けます。つまり、ガベージを出力することさえあります。 \0printf()stdout\0

なぜ'\0'ここで使用する必要がありますか?

\0文字列を終了する必要がない場合は、次の2つのシナリオがあります。

  • 文字列の長さを明示的に簿記している場合は、どのような使用法でも
  • 標準ライブラリを使用している場合、APIは暗黙的\0に文字列にを追加します。

あなたの場合、あなたはすでにあなたのために働いている2番目のシナリオを持っています。

array[s.size()] = '\0';

上記のコードステートメントは、あなたの例では冗長です。

あなたの例では、を使用strncpy()すると役に立たなくなります。文字をにstrncpy()コピーします。文字列のコピー後にスペースが残っている場合は、ヌル終了が追加されることに注意してください。サイズがaなので、自動的に追加されます。 s.size()arrayarrays.size() + 1\0

于 2012-06-08T04:23:33.093 に答える
6

'\0'はヌル終了文字です。文字配列にそれがなく、strcpyを実行しようとすると、バッファオーバーフローが発生します。多くの関数は、メモリの読み取りまたは書き込みをいつ停止する必要があるかを知るために、これに依存しています。

于 2012-06-08T04:27:50.973 に答える
4
strncpy(array, s.c_str(), s.size());
array[s.size()] = '\0';

ここで「\0」を使用する必要があるのはなぜですか?

その2行目はスペースの無駄です。strncpyは、使用方法を知っている場合、すでにnull終了を追加しています。コードは次のように書き直すことができます。

strncpy(array, s.c_str(), s.size()+1);

strncpyは一種の奇妙な関数であり、最初のパラメーターが3番目のパラメーターのサイズの配列であると想定しています。したがって、文字列のコピー後にスペースが残っている場合にのみ、null終了をコピーします。

この場合、memcpy()を使用することもできます。コードの直感性が低下する可能性がありますが、少し効率が向上します。

于 2012-06-08T06:28:45.270 に答える
2

Cでは、文字列をchar(またはw_char)の配列で表し、特殊文字を使用して文字列の終わりを示します。配列のインデックス0に文字列の長さを格納するPascalとは対照的に(したがって、文字列には文字数に厳しい制限があります)、理論的には、文字列(として表される)の文字数に制限はありません。文字の配列)はCで持つことができます。

特殊文字は、Cのデフォルトライブラリおよび他のライブラリのすべての関数でNULであることが期待されています。文字列の正確な長さに依存するライブラリ関数を使用する場合は、文字列をNULで終了する必要があります。独自の終了文字を完全に定義することはできますが、文字列(文字の配列として)を含むライブラリ関数が期待どおりに機能しない可能性があり、あらゆる種類のエラーが発生することを理解する必要があります。

与えられたコードスニペットでは、割り当てられた配列にごみデータがあるかどうかわからないため、終了文字を明示的にNULに設定する必要があります。大きなコードでは、文字の配列の初期化が表示されない場合があるため、これも良い習慣です。

于 2012-06-08T04:40:22.710 に答える