strcasecmp():非标准函数?

时间:2015-06-29 23:34:41

标签: c string comparison

前几天我在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()有这些限制?

4 个答案:

答案 0 :(得分:3)

strcasecmp不符合C或C ++标准。它由POSIX.1-2001和4.4BSD定义。

如果您的系统POSIX或BSD兼容,您将没有任何问题。否则,该功能将不可用。

答案 1 :(得分:1)

“函数是非标准的”意味着函数声明和合同未在C国际标准中指定。

“这使得代码不可移植”意味着实现strcasecmp()不需要实现,因此您的代码不完全符合标准,并且不能保证由严格符合标准的编译器编译。

strcasecmp()本身是POSIX.1-20014.4BSD规范(link)的一部分。

答案 2 :(得分:0)

简短回答:由于strcasecmp()不符合C标准,因此不符合标准。

strcasecmp()在4.4BSD,POSIX.1-2001等流行标准中定义。

无壳功能的定义打开了挑剔细节的大门。这些通常涉及无案例比较的+-结果,而不仅仅是OP使用的0non-0。特别是:

  

在POSIX语言环境中,strcasecmp()和strncasecmp()的行为就好像字符串已经转换为小写,然后执行字节比较。结果未在其他语言环境中指定。

问题在于大写和小写字母没有1到1的映射。考虑一个拥有Eeé但没有É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()仅在intunsigned char范围内为EOF定义。

答案 3 :(得分:-1)

另一种方法是使用tolower()将输入封装到小写,这是标准的。然后你可以使用标准的strcmp()。