C语言stristr函数如何实现不区分大小写查找?

99ANYc3cd6
预计阅读时长 15 分钟
位置: 首页 C语言 正文

stristr 不是标准 C 库函数

最重要的一点是:stristr 函数并不是 C 标准库(如 string.h)中的一部分

c语言 stristr
(图片来源网络,侵删)

它是一个常见的非标准扩展,通常出现在 Windows 平台(特别是微软的 Visual C++ / MSVC 编译器)中,或者是一些第三方库(如 PHP 的源码中)为了方便而实现的。

  • 在标准 C 中,你找不到 stristr 的声明。
  • 在 Windows (MSVC) 中,你可以通过包含 <string.h> 来使用它。
  • 在 Linux (GCC/Clang) 中,默认情况下没有这个函数。

stristr 的功能

stristr 的功能与标准库函数 strstr 非常相似,但有一个关键区别:

  • strstr: 在一个字符串(haystack)中查找另一个字符串(needle)的第一次出现,它是大小写敏感的。
  • stristr: 在一个字符串(haystack)中查找另一个字符串(needle)的第一次出现,它是大小写不敏感的。

你可以把它理解为 "case-insensitive string" (大小写不敏感的字符串) 的缩写。


函数原型

char *stristr(const char *haystack, const char *needle);

参数:

c语言 stristr
(图片来源网络,侵删)
  • haystack: 要被搜索的字符串(“草堆”)。
  • needle: 要在 haystack 中查找的子字符串(“针”)。

返回值:

  • 如果找到 needle,则返回一个指向 haystack匹配子字符串的起始位置的指针。
  • 如果没有找到 needle,则返回 NULL
  • needle 是一个空字符串(),则行为通常是返回 haystack 本身。

与标准函数 strstr 的对比

函数 功能 大小写敏感 标准库
strstr 查找子字符串 是 (<string.h>)
stristr 查找子字符串 (通常是平台扩展)

如何在不同环境下使用 stristr

在 Windows (MSVC) 中

在 Windows 上使用 Visual Studio 编译器时,stristr 是可用的,非常方便。

#include <stdio.h>
#include <string.h> // stristr 通常在这里声明
int main() {
    const char *haystack = "Hello, this is a Test String.";
    const char *needle = "test";
    char *result = stristr(haystack, needle);
    if (result != NULL) {
        printf("子字符串 \"%s\" 在 \"%s\" 中找到,\n", needle, haystack);
        printf("匹配位置: %ld\n", result - haystack); // 计算偏移量
        printf("从该位置开始的子串: \"%s\"\n", result);
    } else {
        printf("子字符串 \"%s\" 在 \"%s\" 中未找到,\n", needle, haystack);
    }
    return 0;
}

输出:

子字符串 "test" 在 "Hello, this is a Test String." 中找到。
匹配位置: 16
从该位置开始的子串: "Test String."

注意,stristr 找到了 "Test",因为它忽略了大小写差异。

c语言 stristr
(图片来源网络,侵删)

在 Linux (GCC/Clang) 中

在 Linux 或其他类 Unix 系统上,GCC/Clang 默认不提供 stristr,如果你需要这个功能,你有以下几种选择:

选择 A: 手动实现一个

这是最推荐、最可移植的方法,你可以自己写一个大小写不敏感的字符串查找函数。

#include <stdio.h>
#include <ctype.h> // 用于 tolower()
// 手动实现一个大小写不敏感的 strstr
char *my_stristr(const char *haystack, const char *needle) {
    if (!*needle) {
        return (char *)haystack; // 空字符串总是“找到”
    }
    for (; *haystack; haystack++) {
        const char *h = haystack;
        const char *n = needle;
        // 比较当前 haystack 位置开始的字符
        while (tolower((unsigned char)*h) == tolower((unsigned char)*n)) {
            if (!*n) {
                return (char *)haystack; // 完全匹配
            }
            h++;
            n++;
        }
    }
    return NULL; // 未找到
}
int main() {
    const char *haystack = "Hello, this is a Test String.";
    const char *needle = "test";
    char *result = my_stristr(haystack, needle);
    if (result != NULL) {
        printf("子字符串 \"%s\" 在 \"%s\" 中找到,\n", needle, haystack);
        printf("匹配位置: %ld\n", result - haystack);
        printf("从该位置开始的子串: \"%s\"\n", result);
    } else {
        printf("子字符串 \"%s\" 在 \"%s\" 中未找到,\n", needle, haystack);
    }
    return 0;
}

这个 my_stristr 函数在所有标准 C 编译器上都能工作。

选择 B: 使用平台特定的条件编译

如果你的代码需要同时在 Windows 和 Linux 上编译,可以使用 #ifdef 来选择不同的实现。

#include <stdio.h>
#ifdef _WIN32
    #include <string.h> // MSVC 的 stristr
#else
    // Linux/macOS 上使用我们自己的实现
    #include <ctype.h>
    char *stristr(const char *haystack, const char *needle) {
        // ... 这里放上上面 my_stristr 的实现 ...
    }
#endif
// main 函数保持不变

特性 描述
标准性 非标准,是平台扩展。
功能 haystack 中查找 needle不区分大小写
可用性 Windows (MSVC) 默认提供,Linux (GCC/Clang) 默认不提供。
最佳实践 为了代码的可移植性,建议自己实现一个 my_stristr 函数,而不是依赖平台特定的功能。
核心实现思路 strstr 的逐字符比较逻辑,改为使用 tolower()toupper() 函数对每个字符进行标准化后再比较。

希望这个详细的解释能帮助你完全理解 stristr 在 C 语言中的使用!

-- 展开阅读全文 --
头像
织梦关键词怎么添加?
« 上一篇 04-18
织梦入学会的服装有何独特之处?
下一篇 » 04-18

相关文章

取消
微信二维码
支付宝二维码

目录[+]