7

私の理解では、strcmp()('n'なし)は、いずれかの引数にnull文字が含まれていると、すぐに処理を停止して結果を返します。
したがって、引数の1つが100%確実にnullで終了することがわかっている場合(たとえば、文字列リテラルである場合)、3番目の一部としてstrncmp()の呼び出しで(「n」を使用して)使用してもセキュリティ上の利点はありません。strlen()既知の文字列の長さに比較を制限する引数。これstrcmp()は、既知の終了文字列よりも多くの文字を読み取ることはないためです。

実際、最初の2つの引数のいずれかstrncmp()で長さ引数がaである呼び出しは、式を評価することによって既知の終了文字列のサイズで線形の時間を浪費するというstrlen()点でのみ異なるように思われます。strcmp()strlen()

検討:

サンプルコードA:

if (strcmp(user_input, "status") == 0)
    reply_with_status();

サンプルコードB:

if (strncmp(user_input, "status", strlen("status")+1) == 0)
    reply_with_status();

前者には後者よりもメリットがありますか?他の人のコードでよく見かけるからです

これらの機能がどのように機能するかについての理解に欠陥がありますか?

4

6 に答える 6

5

あなたの特定の例では、次のstrncmp理由で使用するのは有害だと思います。

  • strlenとにかくスキャンを使用します
  • 文字列リテラルの繰り返し"status"
  • 文字列が実際に等しいことを確認するために1を加算

これらはすべて混乱を招きます。どちらの場合も、user_input実際に6文字より短く、テスト文字列と同じ文字が含まれている場合は、オーバーフローから保護されません。

それは例外的でしょう。入力文字列に常にテスト文字列の文字数よりも多くのメモリがあることがわかっている場合は、心配する必要はありません。そうでなければ、心配するか、少なくともそれを考慮する必要 があるかもしれません。strncmp大きなバッファ内のものをテストするのに役立ちます。

私の好みはコードの可読性です。

于 2013-02-14T22:19:33.357 に答える
4

はい、そうです。strncmpでstrlenを使用すると、文字列にnullが見つかるまでポインタをトラバースします。これにより、機能的にはstrcmpと同等になります。

于 2013-02-14T22:13:42.047 に答える
4

あなたが与えた特定のケースでは、それは確かに役に立たない。ただし、わずかな変更がより一般的です。

if (strncmp(user_input, "status", strlen("status")) == 0)
    reply_with_status();

user_input このバージョンは、で始まるかどうかをチェックするだけ"status"なので、セマンティクスが異なります。

于 2013-02-14T22:27:43.613 に答える
2

文字列の先頭が入力と一致するかどうかを確認するためのトリックを超えて、strncmpは、割り当てられたスペースの終わりの前に文字列がnullで終了することが100%確実でない場合にのみ役立ちます。

したがって、ユーザー入力を取り込んだ固定サイズのバッファーがある場合は、次を使用できます。

strncmp(user_input, "status", sizeof(user_input))

したがって、比較がオーバーフローしないようにしてください。

ただし、この場合、user_inputがnullで終了していない場合は、user_inputがステータスの先頭と一致するかどうかを実際にチェックするため、注意する必要があります。

より良い方法は次のように言うことかもしれません:

if (user_input[sizeof(user_input) - 1] != '\0') {
  // handle it, since it is _not_ equal to your string
  // unless filling the buffer is valid
}
else if (strcmp(user_input, "status")) { ... }
于 2013-03-07T21:35:01.710 に答える
0

さて、これはstrncmp()の特に有用な使用法ではないことに同意し、strcmp()よりもこれに利点は見られません。

+1ただし、 afterを削除してコードを変更するstrlenと、便利になります。

 strncmp(user_input, "status", strlen("status"))

これは、の最初の6文字を `" status "と比較するためですuser_input。これは、少なくとも時々意味があります。

したがって、そこにある場合+1、それは通常になりますstrcmp-そしてそれは長さを計算するのに時間の無駄です。しかし、がなければ+1、それは非常に有用な比較です(適切な状況下で)。

于 2013-02-14T22:27:13.967 に答える
0

strncmp()の使用は制限されています。通常のstrcmp()は、2つの文字列のいずれかでNULに遭遇すると停止します。(その場合、文字列は異なります)Strncmp()は停止し、ゼロを返します(「文字列は最初のN文字で等しい」)

stncmp()の可能な使用法の1つは、重要でない部分までのオプションの解析です。

if (!strncmp("-st", argv[xx], 3)) {}

、「-string」、「-state」、「-st0」の場合はゼロを返しますが、「-sadistic」の場合はゼロを返しません

于 2013-02-14T22:32:22.727 に答える