我认为如果第一个字符串大于第二个字符串,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下使用GCC 4.3,以防万一。
答案 0 :(得分:2)
strcmp
和其他字符串函数实际上并不知道。在大多数posix机器上,C / C ++ char
在内部是utf8,这使得大多数事情在阅读和写作方面“正常工作”,并提供了库的理解和操作的选项码点。但默认的string.h
函数对文化不敏感,对比较utf字符串一无所知。您可以查看strcmp
的源代码,亲眼看看,尽可能实现天真(这意味着它也比国际化感知比较函数更快)。
我刚回答了这个in another question - 您需要使用支持UTF的字符串库,例如IBM的优秀ICU - International Components for Unicode。
答案 1 :(得分:1)
保存为8位ASCII编码,'A' == 65
和'Ä'
等于-61,如果您认为它是unsigned char
。无论如何,'Ä'
是严格正面的并且大于2 ^ 7-1,你只是打印它就像签名一样。
如果您认为'Ä'
是unsigned char
(它是),则其字符集中的值为195。因此,strcmp(65, 195)
正确报告了-1
。
答案 2 :(得分:1)
strcmp()将字符作为无符号ASCII值。所以,你的A-with-double-dots不是char -61,它是char 195(或者196,如果我的数学错误的话)。
答案 3 :(得分:1)
strcmp
和类似的比较函数将字符串中的字节视为unsigned char
s,由7.24.4节中的标准指定,第1点(C99中为7.21.4)
比较函数memcmp,strcmp和strncmp返回的非零值的符号由第一对字符(均解释为unsigned char)的值之间的差异符号确定在被比较的对象中有所不同。
(强调我的)。
原因可能是这样的解释维持了常见编码中代码点之间的顺序,而将它们解释为签名char
则不然。
答案 4 :(得分: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.
答案 5 :(得分:-1)
当输入字符集超过时,在C中正确处理字符串 UTF8你应该使用标准库的宽字符设施 字符串和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;
}
然后它将给出正确的结果(GCC 4.6.3)。您不需要特殊的库。