1. ホーム
  2. c

[解決済み] C99 stricmp()とstrnicmp()を削除しますか?

2022-02-07 10:53:09

質問

機能 stricmp()strnicmp() はC99で削除されたのですか? 私はいつも警告を受ける 関数 stricmp() の暗黙の宣言 (また strnicmp() )をC99に対してコンパイルしようとしたとき。 例えば、以下のような簡単なコードでは、この警告が表示されます。

#include<string.h>
#include<stdio.h>

char arr[100]="hello";
char arr2[100]="hEllo";

int main()
{
   int n=-1;
   printf("%d\n",n);
   n=strnicmp(arr,arr2,3);   // the same when use the function stricmp();
   printf("%d\n",n);

   getchar();
   return 0;
}

このコード片をC99に対してコンパイルしようとすると( gcc -Wall -std=c99 main.c -o main という警告が表示されます。しかし -std=c99 警告は表示されません。 しかし、暗黙の宣言の警告があったとしても、私のコードは正しく動作します。

なぜでしょうか?バグなんでしょうか?もしバグでないなら、その警告を発生させるC99の変更点はいったい何なのでしょうか?

解決方法は?

C99でコンパイルした場合、C99規格に準拠することになりますが、C99規格には stricmp() . C99 スイッチなしでコンパイルした場合、そのコードは stricmp() . (与えられた gcc なし -std=c99 暗黙の宣言を許容するC89/90規格にコンパイルされる可能性があります)。

として ヨアヒム・ピレボーグ がコメントしたように、無感覚な比較はCの標準には含まれていません。

C99では暗黙の関数は診断(この場合は警告)を必要とします。 C99では、暗黙的な関数の使用は警告を発生させない。 この関数は これ コンパイラのライブラリで、使用する前に宣言されているかどうかが問題なのです。

自分で作るのは簡単。

int wal_stricmp(const char *a, const char *b) {
  int ca, cb;
  do {
     ca = (unsigned char) *a++;
     cb = (unsigned char) *b++;
     ca = tolower(toupper(ca));
     cb = tolower(toupper(cb));
   } while (ca == cb && ca != '\0');
   return ca - cb;
}


注:コーディングして A-Z 一致 a-z 文字列を考慮しない比較ルーチンは、一様にうまく動作する傾向があります。 しかし オーダー 思いやりが大文字で行われたか小文字で行われたかによって、 "abc" と "_bc" が前に来たり後に来たりすることがあるのです。 '_' ASCIIでは、大文字と小文字の間に存在します。 国際化やロケールの問題で、状況はより複雑になります。 私のコード例では、大文字と小文字の数が異なる問題に対処するために、変換のラウンドトリップを使用しています。 char が小文字のものと1対1に対応しない。 大文字小文字を区別しない複雑な比較は、UTFエンコーディングとその大文字小文字の定義を使わざるを得ないというのがIMOの見解です。


[2020年版を編集する]

2の補数や2の補数でない寂しいプラットフォームに対応するために、コードの修正が必要です。 以前のコードでは、+0と-0を折りたたんで unsigned 0. 0だけが0に変換されるはずです。 unsigned char よりも signed char と変換してください。

注:2の補数でない場合の適切な処理については、現在ではほとんど学術的なものです。

// ca = (unsigned char) *a++;
ca = *((unsigned char *) a++);
// also cb