strstr 函数使用教程:C/C++ 字符串查找实例 – wiki词典

strstr 函数使用教程:C/C++ 字符串查找实例

在 C/C++ 编程中,字符串查找是一个非常常见的操作。strstr 函数是 C 标准库中用于在一个字符串中查找另一个字符串的函数。本文将详细介绍 strstr 函数的定义、使用方法、实例以及在使用时需要注意的事项。

1. strstr 函数概述

strstr 函数(string-string)用于在给定字符串(haystack)中查找第一个出现的子字符串(needle)。它是 C 语言标准库 <string.h>(在 C++ 中是 <cstring>)的一部分。

函数原型:

c
char *strstr(const char *haystack, const char *needle);

参数说明:

  • haystack: 指向要搜索的 C 风格字符串的指针。
  • needle: 指向要查找的子字符串的指针。

返回值:

  • 如果 needle 字符串在 haystack 字符串中找到,strstr 函数返回一个指向 haystackneedle 第一次出现位置的指针。
  • 如果 needle 字符串没有在 haystack 字符串中找到,函数返回 NULL
  • 如果 needle 是一个空字符串(""),函数返回 haystack 本身。

2. strstr 函数的工作原理

strstr 函数从 haystack 字符串的开头开始,逐个字符地与 needle 字符串进行比较。一旦找到一个匹配 needle 完整长度的序列,它就返回该匹配的起始位置。查找过程是区分大小写的。

3. C 语言使用实例

以下是一个简单的 C 语言示例,演示如何使用 strstr 函数查找子字符串。

“`c

include

include // 包含 strstr 函数的头文件

int main() {
const char text = “Hello, world! This is a test string.”;
const char
sub1 = “world”;
const char sub2 = “example”;
const char
sub3 = “string”;
const char *sub4 = “”; // 空字符串

char *result;

// 查找 "world"
result = strstr(text, sub1);
if (result != NULL) {
    printf("'%s' found in '%s' at position: %ld\n", sub1, text, result - text);
    // 输出从匹配位置开始的子字符串
    printf("Substring from match: '%s'\n", result);
} else {
    printf("'%s' not found in '%s'\n", sub1, text);
}

// 查找 "example" (不存在)
result = strstr(text, sub2);
if (result != NULL) {
    printf("'%s' found in '%s' at position: %ld\n", sub2, text, result - text);
} else {
    printf("'%s' not found in '%s'\n", sub2, text);
}

// 查找 "string"
result = strstr(text, sub3);
if (result != NULL) {
    printf("'%s' found in '%s' at position: %ld\n", sub3, text, result - text);
} else {
    printf("'%s' not found in '%s'\n", sub3, text);
}

// 查找空字符串
result = strstr(text, sub4);
if (result != NULL) {
    printf("Empty string found at the beginning of '%s'. Result pointer: %p, text pointer: %p\n", text, (void*)result, (void*)text);
    // 验证返回的是否是 haystack 本身
    if (result == text) {
        printf("As expected, searching for an empty string returns the original string pointer.\n");
    }
}

return 0;

}
“`

输出示例:

'world' found in 'Hello, world! This is a test string.' at position: 7
Substring from match: 'world! This is a test string.'
'example' not found in 'Hello, world! This is a test string.'
'string' found in 'Hello, world! This is a test string.' at position: 29
Empty string found at the beginning of 'Hello, world! This is a test string.'. Result pointer: 0x... , text pointer: 0x...
As expected, searching for an empty string returns the original string pointer.

在上面的示例中,result - text 计算了子字符串在主字符串中的起始偏移量(位置)。

4. C++ 语言使用实例

在 C++ 中,虽然可以使用 <cstring> 包含 strstr 函数,但更推荐使用 std::string 类的成员函数 find(),因为它更符合 C++ 的面向对象特性,并且处理内存和空终止符更安全。然而,如果处理的是 C 风格字符串(const char*),strstr 仍然是一个有效且常用的选择。

“`cpp

include

include // 包含 strstr 函数的头文件

include // 包含 std::string 类

int main() {
// 使用 C 风格字符串和 strstr
const char text_c = “C++ programming is powerful.”;
const char
sub_c = “programming”;

char *result_c = std::strstr(text_c, sub_c);
if (result_c != nullptr) {
    std::cout << "C-style: '" << sub_c << "' found at position: " << result_c - text_c << std::endl;
    std::cout << "Substring from match: '" << result_c << "'\n" << std::endl;
} else {
    std::cout << "C-style: '" << sub_c << "' not found." << std::endl;
}

// 使用 std::string 和其 find() 方法 (C++ 推荐方式)
std::string text_cpp = "C++ programming is powerful.";
std::string sub_cpp = "powerful";
std::string sub_not_found = "java";

size_t pos = text_cpp.find(sub_cpp);
if (pos != std::string::npos) { // std::string::npos 表示未找到
    std::cout << "C++ std::string: '" << sub_cpp << "' found at position: " << pos << std::endl;
    std::cout << "Substring from match: '" << text_cpp.substr(pos) << "'\n" << std::endl;
} else {
    std::cout << "C++ std::string: '" << sub_cpp << "' not found." << std::endl;
}

pos = text_cpp.find(sub_not_found);
if (pos != std::string::npos) {
    std::cout << "C++ std::string: '" << sub_not_found << "' found at position: " << pos << std::endl;
} else {
    std::cout << "C++ std::string: '" << sub_not_found << "' not found." << std::endl;
}

return 0;

}
“`

输出示例:

“`
C-style: ‘programming’ found at position: 4
Substring from match: ‘programming is powerful.’

C++ std::string: ‘powerful’ found at position: 21
Substring from match: ‘powerful.’

C++ std::string: ‘java’ not found.
“`

5. 注意事项和常见问题

  1. 空字符串 needle: 如前所述,如果 needle 是一个空字符串 ""strstr 会返回 haystack 指针本身。这通常被视为 needlehaystack 的开头被找到。
  2. 区分大小写: strstr 是区分大小写的。例如,在 “Hello World” 中查找 “world” 会失败。如果需要不区分大小写的查找,你需要手动实现一个版本,或者将两个字符串都转换为相同的大小写(例如,都转换为小写)后再进行比较。
  3. NULL 参数: 如果 haystackneedle 中的任何一个为 NULL,调用 strstr 将导致未定义行为(通常是程序崩溃)。在使用 strstr 之前,始终确保参数是非空指针。
  4. 返回指针的修改: strstr 返回的指针指向 haystack 内部的内存。如果你通过这个指针修改数据,你将修改原始的 haystack 字符串。请务必小心。
  5. C++ 推荐 std::string::find: 在 C++ 中,当使用 std::string 对象时,强烈建议使用 std::string::find() 方法。它提供了类型安全、自动内存管理和更直观的接口。

6. strstr 的替代方案

  • C++ std::string::find(): 对于 std::string 对象,这是最推荐的字符串查找方法。它返回子字符串的起始索引,而不是指针,并且查找失败时返回 std::string::npos
  • C 语言的 strpbrk(): 如果你需要查找字符串中包含在另一个字符串中的任意一个字符,可以使用 strpbrk()
  • C 语言的 strchr()strrchr(): 如果你只需要查找单个字符的第一次或最后一次出现,这两个函数更为合适。
  • 自定义实现: 对于更复杂的查找需求,例如正则表达式匹配,或者不区分大小写的查找,你可能需要使用更高级的库(如 C++ 的 <regex>)或实现自己的查找逻辑。

7. 总结

strstr 函数是 C/C++ 中一个基本且高效的 C 风格字符串查找工具。它在处理 const char* 类型的字符串时非常有用,但在 C++ 中使用 std::string 时,std::string::find() 通常是更安全和更现代的选择。理解 strstr 的工作原理、返回值和注意事项,可以帮助你编写健壮且高效的字符串处理代码。

滚动至顶部