【发布时间】:2020-06-06 02:34:37
【问题描述】:
我正在尝试在 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", "_"));具有相同的结果,但这意味着这两个不区分大小写的调用中的 一个 是将不同意其区分大小写的对应项。 -
您所指的
strcasecmp的描述似乎不准确。更多详细信息请参阅投票的答案。 -
这是唯一有意义的事情。一个写着
A < _ && a > _ && A == a的函数会导致很多问题。 -
旁白:“我正在尝试用 C 重新实现 strcasecmp 函数” --> 虽然代码没有显示,但请务必比较“as if”
unsigned char。 C17/18 "字符串处理" --> "对于本子条款中的所有函数,每个字符都应被解释为其类型为 unsigned char"。一旦char值超出 ASCII 范围 0-127,这就会产生影响。 -
关于内置和不内置输出的差异:两者都说相同,因为它们的结果相同 0,并且您没有 ==0 的示例。但是您可以看到算法大放异彩:一些返回值是第一个不相等字符的差异。