前几天我在CodeReview上创建了一个帖子。一个回答我问题的人建议我不要使用strcasecmp()因为“函数是非标准的[并且]这使得[my]代码不可移植。”这就是我使用它的方式:
int playGame()
{
char scanned[3];
printf("Do you wish to play tick-tack-toe?\n");
scanf("%s", scanned);
if(strcasecmp(scanned,"yes")==0)
startGame();
else
{
if (strcasecmp(scanned,"no")==0 || strcasecmp(scanned,"nah")==0 || strcasecmp(scanned,"naw")==0)
{
printf("That's too bad!/nThis program will now end.");
return 1;
}
printf("Not valid input!/nThis program will now end.");
return 1;
}
return 0;
}
有人可以更深入地解释为什么strcasecmp()有这些限制?
答案 0 :(得分:3)
strcasecmp不符合C或C ++标准。它由POSIX.1-2001和4.4BSD定义。
如果您的系统POSIX或BSD兼容,您将没有任何问题。否则,该功能将不可用。
答案 1 :(得分:1)
“函数是非标准的”意味着函数声明和合同未在C国际标准中指定。
“这使得代码不可移植”意味着实现strcasecmp()
不需要实现,因此您的代码不完全符合标准,并且不能保证由严格符合标准的编译器编译。
strcasecmp()
本身是POSIX.1-2001
和4.4BSD
规范(link)的一部分。
答案 2 :(得分:0)
简短回答:由于strcasecmp()
不符合C标准,因此不符合标准。
strcasecmp()
在4.4BSD,POSIX.1-2001等流行标准中定义。
无壳功能的定义打开了挑剔细节的大门。这些通常涉及无案例比较的+
或-
结果,而不仅仅是OP使用的0
或non-0
。特别是:
在POSIX语言环境中,strcasecmp()和strncasecmp()的行为就好像字符串已经转换为小写,然后执行字节比较。结果未在其他语言环境中指定。
问题在于大写和小写字母没有1到1的映射。考虑一个拥有E
,e
和é
但没有É
但toupper('é')
- >的本地人'E'
。然后使用“好像字符串已转换为小写”,'E'
有2个选项。
作为candidate便携式解决方案,考虑将字母往返(从上到下)以应对非1对1映射:
int SGA_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;
}
如果您不想往返值,请使用:
ca = tolower(ca);
cb = tolower(cb);
明细:toupper()
和tolower()
仅在int
和unsigned char
范围内为EOF
定义。
答案 3 :(得分:-1)
另一种方法是使用tolower()将输入封装到小写,这是标准的。然后你可以使用标准的strcmp()。