我正在尝试在C中重新实现strcasecmp
函数,并注意到比较过程中似乎存在不一致。
从man strcmp
中可以得知:
strcmp()函数比较两个字符串s1和s2。 它不考虑区域设置(对于区域设置感知比较,请参见strcoll(3))。 如果找到s1小于,等于或大于s2,则返回一个整数小于,等于或大于零。
从man strcasecmp
中可以得知:
strcasecmp()函数执行逐字节比较字符串s1和s2,忽略字符的大小写。如果找到s1小于,等于或大于s2,则返回一个整数小于,等于或大于零。
int strcmp(const char *s1, const char *s2);
int strcasecmp(const char *s1, const char *s2);
根据这些信息,我不理解以下代码的结果:
#include <stdio.h>
#include <string.h>
int main()
{
// ASCII values
// 'A' = 65
// '_' = 95
// 'a' = 97
printf("%i\n", strcmp("A", "_"));
printf("%i\n", strcmp("a", "_"));
printf("%i\n", strcasecmp("A", "_"));
printf("%i\n", strcasecmp("a", "_"));
return 0;
}
输出:-1 # "A" is less than "_"
1 # "a" is more than "_"
2 # "A" is more than "_" with strcasecmp ???
2 # "a" is more than "_" with strcasecmp
看起来,如果s1
中的当前字符是一个字母,它总是被转换为小写,无论s2
中的当前字符是否是字母。
有人能解释一下这种行为吗?难道第一行和第三行不应该是相同的吗?
提前感谢!
PS:
我在Manjaro上使用gcc 9.2.0
。
此外,当我使用-fno-builtin
标志进行编译时,我得到的结果是:
-30
2
2
2
我猜是因为该程序没有使用gcc的优化函数,但问题仍然存在。
printf("%i\n", strcasecmp("a", "_"));
这应该与printf("%i\n", strcasecmp("A", "_"));
有相同的结果。但这意味着这两个不区分大小写的调用中的 一个 将与其区分大小写的对应项产生不一致。 - anton.burgerstrcasecmp
描述并不准确。更多细节请查看得到赞同的回答。 - Jabberwocky