stricmp 是一个不区分大小写的字符串比较函数,它会逐个字符比较两个字符串,忽略大小写差异,并返回一个整数值来表示比较结果。
函数原型
stricmp 的函数原型通常如下:
int stricmp(const char *str1, const char *str2);
参数:
str1: 第一个要比较的字符串。str2: 第二个要比较的字符串。
返回值:
- 小于 0 (
< 0):str1小于str2,在字典序中,str1出现在str2之前。 - 等于 0 (
== 0):str1等于str2,两个字符串的内容完全相同(忽略大小写)。 - 大于 0 (
> 0):str1大于str2,在字典序中,str1出现在str2之后。
工作原理
stricmp 的工作方式与标准的 strcmp 非常相似,关键区别在于它不区分大小写。
- 逐个字符比较:函数从两个字符串的第一个字符开始,依次向后比较。
- 大小写转换:在比较每个字符之前,
stricmp会将两个字符都转换成统一的大小写(通常是转换为大写或小写)。 - 比较 ASCII 码:然后比较转换后字符的 ASCII 码值。
- 比较
'A'和'a':stricmp会将它们都转换成'A'(或'a'),然后发现它们是相等的。- 而
strcmp会直接比较'A'(65) 和'a'(97),得出'A'小于'a'的结论。
- 比较
- 终止条件:
- 如果在某个位置发现两个字符不相等,函数立即返回它们的差值。
- 如果比较完一个字符串的所有字符,另一个字符串也同时结束(即
'\0'),则返回 0,表示字符串相等。 - 如果一个字符串先结束,而另一个字符串还有剩余字符,则较短的字符串被认为更小。
示例代码
下面通过几个例子来直观地理解 stricmp 的行为。
#include <stdio.h>
#include <string.h> // 包含 stricmp 的头文件
int main() {
// 示例 1: 两个字符串完全相同(忽略大小写)
char str1[] = "Hello";
char str2[] = "HELLO";
int result1 = stricmp(str1, str2);
printf("stricmp(\"%s\", \"%s\") = %d\n", str1, str2, result1); // 输出: 0
// 示例 2: str1 在字典序中大于 str2
char str3[] = "apple";
char str4[] = "Banana"; // 'B' (66) > 'a' (97) 在 ASCII 中,但 stricmp 会忽略大小写
int result2 = stricmp(str3, str4);
// 'a' vs 'b' -> 'a' < 'b', str3 < str4, 函数返回负数
printf("stricmp(\"%s\", \"%s\") = %d\n", str3, str4, result2); // 输出: 一个负数 (-1)
// 示例 3: str1 在字典序中小于 str2
char str5[] = "Zebra";
char str6[] = "alpha";
int result3 = stricmp(str5, str6);
// 'Z' vs 'a' -> 'Z' (90) > 'a' (97) 在 ASCII 中,但 stricmp 会忽略大小写
// 'z' vs 'a' -> 'z' > 'a', str5 > str6, 函数返回正数
printf("stricmp(\"%s\", \"%s\") = %d\n", str5, str6, result3); // 输出: 一个正数 (1)
// 示例 4: 一个字符串是另一个的前缀
char str7[] = "test";
char str8[] = "testing";
int result4 = stricmp(str7, str8);
printf("stricmp(\"%s\", \"%s\") = %d\n", str7, str8, result4); // 输出: 一个负数
return 0;
}
重要注意事项:可移植性问题
这是使用 stricmp 时最需要注意的一点。
stricmp 不是 C 标准库的一部分,它是特定于编译器和平台的函数,主要存在于:
- Windows (MSVC, MinGW): 在
string.h或strings.h中定义。 - DOS / Turbo C: 同样支持。
在许多其他平台上,如 Linux、macOS(使用 GCC/Clang 编译器)或现代的 C 标准中,stricmp 是不可用的。
在这些平台上,你应该使用标准化的替代函数:
| 函数名 | 头文件 | 平台/标准 | 描述 |
|---|---|---|---|
stricmp |
string.h |
非标准 (Windows/DOS) | 不区分大小写的字符串比较。 |
strcasecmp |
strings.h |
POSIX 标准 (Linux, macOS, etc.) | 功能与 stricmp 完全相同,是 POSIX 标准定义的。 |
strcmp |
string.h |
C 标准库 | 区分大小写的字符串比较。 |
如何编写可移植的代码?
为了确保你的代码可以在不同操作系统上编译和运行,你应该这样做:
使用条件编译
这是最推荐的方法,可以自动选择正确的函数。
#include <stdio.h>
#ifdef _WIN32
// 如果是 Windows 编译器,使用 stricmp
#include <string.h>
#define my_stricmp stricmp
#else
// 如果是 POSIX 系统 (Linux, macOS 等),使用 strcasecmp
#include <strings.h>
#define my_stricmp strcasecmp
#endif
int main() {
char str1[] = "Hello";
char str2[] = "hello";
// 使用我们定义的宏 my_stricmp,而不是直接使用 stricmp
int result = my_stricmp(str1, str2);
if (result == 0) {
printf("字符串相等 (忽略大小写),\n");
} else {
printf("字符串不相等,\n");
}
return 0;
}
自己实现一个
如果不想依赖条件编译,可以自己写一个简单的版本。
#include <stdio.h>
#include <ctype.h> // 用于 tolower 或 toupper
// 一个简单的、可移植的不区分大小写比较函数
int my_stricmp(const char *s1, const char *s2) {
while (*s1 && *s2) {
// 将两个字符都转换为小写进行比较
char c1 = tolower((unsigned char)*s1);
char c2 = tolower((unsigned char)*s2);
if (c1 != c2) {
return c1 - c2;
}
s1++;
s2++;
}
// 处理一个字符串是另一个前缀的情况,或者两个字符串完全相同
return tolower((unsigned char)*s1) - tolower((unsigned char)*s2);
}
int main() {
char str1[] = "Test";
char str2[] = "tesT";
int result = my_stricmp(str1, str2);
if (result == 0) {
printf("字符串相等 (忽略大小写),\n"); // 输出此行
} else {
printf("字符串不相等,\n");
}
return 0;
}
注意: 在自己实现的函数中,使用
(unsigned char)进行类型转换是一个好习惯,可以避免某些字符(如 ASCII 128-255)在tolower函数中的未定义行为。
| 特性 | 描述 |
|---|---|
| 功能 | 不区分大小写地比较两个字符串。 |
| 原型 | int stricmp(const char *str1, const char *str2); |
| 返回值 | <0 (str1 < str2), 0 (str1 == str2), >0 (str1 > str2) |
| 标准性 | 非标准,仅在某些平台(如 Windows)可用。 |
| 可移植替代 | Linux/macOS: strcasecmp (需 #include <strings.h>) |
| 最佳实践 | 使用条件编译 (#ifdef _WIN32) 来选择正确的函数,以确保代码的可移植性。 |
