C99 删除 stricmp() 和 strnicmp()?
C99 remove stricmp() and strnicmp()?
C99 中 stricmp()
和 strnicmp()
函数是否被删除?
当我尝试针对 C99 编译它时,我总是收到警告 implicit declaration of function 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;
}
当我尝试针对 C99(gcc -Wall -std=c99 main.c -o main
) 编译这段代码时,我收到了警告。但是当我在没有 -std=c99
的情况下编译它时,不会抛出任何警告。
但是,即使有隐式声明的警告,我的代码仍然可以正常运行。
这是为什么?那是一个错误吗?如果不是错误,那么 C99 到底是什么变化导致了这个警告?
stricmp
和 strincmp
都是非标准函数。它们从未成为 C 标准的一部分。
代码用C99编译时,符合C99标准,没有stricmp()
。当代码在没有 C99 开关的情况下编译时,它符合实现 stricmp()
的未知标准。 (假设 gcc
没有 -std=c99
,可能会编译为 C89/90 标准,允许隐式声明。)
正如 @Joachim Pileborg 评论的那样,不敏感比较不是 C 标准的一部分。
对于 C99,隐式函数需要诊断(在本例中为警告)。如果没有 C99,函数的隐式使用不会产生警告。这些函数存在于 this 编译器的库中 - 这只是函数在使用前声明的问题。
自己制作很容易:
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 != '[=10=]');
return ca - cb;
}
注意:当编码并试图使 A-Z
匹配 a-z
时,字符串不敏感的比较例程往往会很好地工作。但是当尝试 order 字符串时,事情很快就会失控。 "abc" vs. "_bc" 可以出现在另一个之前或之后,这取决于 compassion 是大写还是小写。 '_'
,在ASCII中,存在于大小写字母之间。随着国际化和区域设置问题,情况变得更加复杂。我的代码示例使用往返转换来处理大写 char
的数量与小写字母之间没有一对一映射的问题。 IMO 健壮的不区分大小写比较的复杂性要求使用 UTF 编码及其大小写定义。
[编辑 2020]
为了应对那些孤立的非 2 补码和 2 补码平台,需要进行代码更正。早期的代码会将 +0 和 -0 折叠成 unsigned
0。只有 +0 应该转换为 0。正确地将数据读取为 unsigned char
而不是 signed char
并转换。
注意:非 2 补码的正确句柄现在主要是学术性的。
// ca = (unsigned char) *a++;
ca = *((unsigned char *) a++);
// also cb
C99 中 stricmp()
和 strnicmp()
函数是否被删除?
当我尝试针对 C99 编译它时,我总是收到警告 implicit declaration of function 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;
}
当我尝试针对 C99(gcc -Wall -std=c99 main.c -o main
) 编译这段代码时,我收到了警告。但是当我在没有 -std=c99
的情况下编译它时,不会抛出任何警告。
但是,即使有隐式声明的警告,我的代码仍然可以正常运行。
这是为什么?那是一个错误吗?如果不是错误,那么 C99 到底是什么变化导致了这个警告?
stricmp
和 strincmp
都是非标准函数。它们从未成为 C 标准的一部分。
代码用C99编译时,符合C99标准,没有stricmp()
。当代码在没有 C99 开关的情况下编译时,它符合实现 stricmp()
的未知标准。 (假设 gcc
没有 -std=c99
,可能会编译为 C89/90 标准,允许隐式声明。)
正如 @Joachim Pileborg 评论的那样,不敏感比较不是 C 标准的一部分。
对于 C99,隐式函数需要诊断(在本例中为警告)。如果没有 C99,函数的隐式使用不会产生警告。这些函数存在于 this 编译器的库中 - 这只是函数在使用前声明的问题。
自己制作很容易:
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 != '[=10=]');
return ca - cb;
}
注意:当编码并试图使 A-Z
匹配 a-z
时,字符串不敏感的比较例程往往会很好地工作。但是当尝试 order 字符串时,事情很快就会失控。 "abc" vs. "_bc" 可以出现在另一个之前或之后,这取决于 compassion 是大写还是小写。 '_'
,在ASCII中,存在于大小写字母之间。随着国际化和区域设置问题,情况变得更加复杂。我的代码示例使用往返转换来处理大写 char
的数量与小写字母之间没有一对一映射的问题。 IMO 健壮的不区分大小写比较的复杂性要求使用 UTF 编码及其大小写定义。
[编辑 2020]
为了应对那些孤立的非 2 补码和 2 补码平台,需要进行代码更正。早期的代码会将 +0 和 -0 折叠成 unsigned
0。只有 +0 应该转换为 0。正确地将数据读取为 unsigned char
而不是 signed char
并转换。
注意:非 2 补码的正确句柄现在主要是学术性的。
// ca = (unsigned char) *a++;
ca = *((unsigned char *) a++);
// also cb