C99是否删除stricmp()和strnicmp()?

C99是否删除stricmp()和strnicmp()?,c,string,c99,C,String,C99,C99中是否删除了函数stricmp()和strnicmp()? 当我试图根据C99编译函数stricmp()(以及strnicmp())时,我总是收到警告。 例如,下面的简单代码为我提供了该警告 #include<string.h> #include<stdio.h> char arr[100]="hello"; char arr2[100]="hEllo"; int main() { int n=-1; printf("%d\n",n); n=s

C99中是否删除了函数
stricmp()
strnicmp()
? 当我试图根据C99编译函数stricmp()(以及strnicmp())时,我总是收到警告。 例如,下面的简单代码为我提供了该警告

#include<string.h>
#include<stdio.h>

char arr[100]="hello";
char arr2[100]="hEllo";

int main()
{
   int n=-1;
   printf("%d\n",n);
   n=strnicmp(arr,arr2,3);   // the same when use the function stricmp();
   printf("%d\n",n);

   getchar();
   return 0;
}
#包括
#包括
char arr[100]=“你好”;
char arr2[100]=“你好”;
int main()
{
int n=-1;
printf(“%d\n”,n);
n=strnicmp(arr,arr2,3);//使用函数stricmp()时相同;
printf(“%d\n”,n);
getchar();
返回0;
}
当我试图针对C99编译这段代码时(
gcc-Wall-std=C99 main.c-o main
),我得到了警告。但是当我编译它时,如果没有
-std=c99
,则不会抛出任何警告。 然而,即使有隐式声明的警告,我的代码仍然工作正常


为什么呢?那是虫子吗?如果不是bug,那么C99的具体变化是什么导致了该警告的发生?

stricmp
strincmp
都是非标准功能。它们从来都不是C标准的一部分。

当代码使用C99编译时,它符合C99标准,而C99标准没有
stricmp()
。当代码在没有C99开关的情况下编译时,它符合实现
stricmp()
的未知标准。(给定不带
-std=c99
gcc
,可能编译为C89/90标准,允许隐式声明。)

如前所述,不敏感比较不是C标准的一部分

对于C99隐式函数,需要进行诊断(本例中为警告)。如果没有C99,隐式使用函数不会生成警告。这些函数存在于这个编译器的库中——这只是一个函数在使用前声明的问题

简单到可以自己制作:

int wal_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;
}

注意:当编码并试图使
A-Z
匹配
A-Z
时,不区分字符串的比较例程往往工作得很好。但当试图对字符串进行排序时,事情很快就会失控。“abc”和“_bc”可以在另一个之前或之后出现,这取决于同情是作为大写还是小写字母出现的'',存在于大写和小写字母之间。随着国际化和地区问题的出现,情况变得更加复杂。我的代码示例使用转换的往返过程来处理大写字符数与小写字符数之间没有1对1映射的问题。IMO由于健壮的不区分大小写比较的复杂性,必须使用UTF编码及其大小写定义


[编辑2020]

为了应对那些被遗弃的非2的补码以及2的补码平台,需要进行代码更正。早期的代码将+0和-0折叠成无符号的
0。只有+0应转换为0。适合将数据读取为
无符号字符
而不是
有符号字符
并进行转换

注:非2的补语中的正确句柄现在主要是学术性的

// ca = (unsigned char) *a++;
ca = *((unsigned char *) a++);
// also cb

这些函数从未出现在C标准中,事实上,C标准中没有不区分大小写的字符串比较函数。
stricmp
stracecmp
等函数都是扩展或由其他标准(POSIX、WIndows等)定义的。如果它不是c标准的一部分,那么为什么我只得到警告而不是错误?我的意思是,既然警告是隐式声明,而不是错误,那么该函数确实是以某种异常的方式声明的,是吗?@Walkerala:因为GCC人员决定将函数的隐式声明作为警告而不是错误。使用
-pedantic errors
或更具体地说
-Werror=implicit function declaration
@walkerala:除了
#error
指令外,C标准仅要求对任何违反规则的行为进行诊断。如果编译器的开发人员认为这样更方便,那么该诊断可能是一个非致命警告。GCC经常为早期版本的语言中合法的代码打印警告。教训:不要忽略警告。要获得轻微的性能提升:
ca=*a;a++;if(islower(ca)){ca=toupper(ca);}
等等。为您节省了一些额外的检查。很抱歉,我无法确切理解您为什么在函数中使用“toupper()”和“tolower()”,尽管它非常有效well@walkerlala
toupper()
是一个标准的C函数,它将
int
转换为其大写等效值<代码>'a'
-->
'a'
'a'
-->
'a'
'0'
-->
'0'
等。它对所有
无符号字符
EOF
都有很好的定义。根据语言环境的不同,您可能还会得到
'ä'
-->
'Ä'
,等等。
tolower()
是小写形式的等价物。@Lundin 1)有趣的想法是,评测可以验证性能差异。考虑有时分支最小化会产生更高的速度。2) 另外,考虑到顺序,我们现在有细微的功能差异。IAC,OP的主要问题是一个函数原型。@chux如果islower是从toupper()调用的或是硬编码到toupper()中的,这一点都不重要,您仍然有相同的开销代码。