3

最初の文字列が2番目の文字列よりも大きい場合、strcmpは正の数を返すはずだと思いました。しかし、このプログラム

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

int main()
{
    char A[] = "A";
    char Aumlaut[] = "Ä";
    printf("%i\n", A[0]);
    printf("%i\n", Aumlaut[0]);
    printf("%i\n", strcmp(A, Aumlaut));
    return 0;
}

65、、-61およびを出力し-1ます。

なんで?見落としているものはありますか?UTF-8として保存しているという事実が、物事に影響を与えるのではないかと思いました。2文字で構成され
ているのでご存知でしょう。Äただし、8ビットエンコーディングとして保存し、両方の文字列の長さが1であることを確認しても効果がないため、最終的な結果は同じです。
私は何が間違っているのですか?

重要な場合は、ここで32ビットLinuxでGCC4.3を使用します。

4

6 に答える 6

2

strcmp他の文字列関数は実際にはutfを認識していません。ほとんどのposixマシンでは、C / C ++charは内部的にutf8であり、読み取りと書き込みに関してほとんどのものを「正しく機能」させ、ライブラリがutfコードポイントを理解して操作するオプションを提供します。ただし、デフォルトのstring.h関数はカルチャに依存せず、utf文字列の比較については何も知りません。ソースコードをstrcmp見て、自分の目で確かめることができます。これは、可能な限り単純な実装です(つまり、国際化を意識した比較関数よりも高速です)。

私は別の質問でこれに答えました-IBMの優れたICU-InternationalComponentsforUnicodeなどのUTF対応の文字列ライブラリを使用する必要があります。

于 2012-05-04T08:36:13.347 に答える
1

8ビットASCIIエンコーディングとして保存します。これを。と見なすと、-61と同じになり'A' == 65ます。とにかく、厳密に正であり、2 ^ 7-1より大きい場合は、署名されているかのように印刷しているだけです。'Ä'unsigned char'Ä'

(それが)であると考える場合、その値は文字セットで195'Ä'です。unsigned charしたがって、strcmp(65, 195)正しく報告します-1

于 2012-05-04T08:38:35.567 に答える
1

strcmp()は、文字を符号なしASCII値として受け取ります。つまり、A-with-double-dotsはchar -61ではなく、char 195(または、数学が間違っている場合は196)です。

于 2012-05-04T08:41:23.010 に答える
1

strcmpおよび同様の比較関数unsigned charは、セクション7.24.4のポイント1(C99では7.21.4でした)の標準で指定されているように、文字列内のバイトをsとして扱います。

比較関数memcmp、strcmp、およびstrncmpによって返されるゼロ以外の値の符号は、比較対象のオブジェクトが異なる最初の文字ペア(両方ともunsigned charとして解釈される)の値の差の符号によって決定されます。

(私の強調)。

その理由はおそらく、そのような解釈は一般的なエンコーディングのコードポイント間の順序を維持しますが、それらを符号付きとして解釈することcharはそうではないためです。

于 2012-05-04T09:50:22.760 に答える
0

strcmpのマンページを確認してください。

The strcmp() function compares the two strings s1 and s2. It returns
an integer less than, equal to, or greater than zero if s1 is found,
respectively, to be less than, to match, or be greater than s2.
于 2012-05-04T08:44:33.090 に答える
-1

入力文字セットがUTF8を超えたときにCで文字列を正しく処理するには、文字列とI/Oに標準ライブラリのワイド文字機能を使用する必要があります。プログラムは次のようになります。

#include <wchar.h>
#include <stdio.h>

int main()
{
    wchar_t A[] = L"A";
    wchar_t Aumlaut[] = L"Ä";
    wprintf(L"%i\n", A[0]);
    wprintf(L"%i\n", Aumlaut[0]);
    wprintf(L"%i\n", wcscmp(A, Aumlaut));
    return 0;
}

その後、正しい結果が得られます(GCC4.6.3)。特別なライブラリは必要ありません。

于 2012-05-04T09:07:22.997 に答える