C99是否删除stricmp()和strnicmp()?
C99中是否删除了函数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
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”可以在另一个之前或之后出现,这取决于同情是作为大写还是小写字母出现的[编辑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@walkerlalatoupper()
是一个标准的C函数,它将int
转换为其大写等效值<代码>'a'
-->'a'
,'a'
-->'a'
,'0'
-->'0'
等。它对所有无符号字符和EOF
都有很好的定义。根据语言环境的不同,您可能还会得到'ä'
-->'Ä'
,等等。tolower()
是小写形式的等价物。@Lundin 1)有趣的想法是,评测可以验证性能差异。考虑有时分支最小化会产生更高的速度。2) 另外,考虑到顺序,我们现在有细微的功能差异。IAC,OP的主要问题是一个函数原型。@chux如果islower是从toupper()调用的或是硬编码到toupper()中的,这一点都不重要,您仍然有相同的开销代码。