首页 > 其他分享 >字符串查找函数strchr 、 strrchr和strstr的简介

字符串查找函数strchr 、 strrchr和strstr的简介

时间:2024-09-07 10:53:46浏览次数:12  
标签:strchr 字符 strstr char str 字符串 strrchr

目录

一、函数简介

1.1. strchr 函数

1.2. strrchr函数

1.3. strstr 函数

二、函数原型

2.1. strchr 函数

参数

返回值

2.1. strchr 函数

参数

返回值

2.2. strstr 函数

参数

返回值

三、函数实现(伪代码)

3.1. strchr 实现

3.2. strrchr 实现

3.3. strstr 实现

四、使用场景

4.1.strchr 使用场景

4.2.strrchr 使用场景

4.3. strstr 使用场景

五、注意事项

5.1. 检查返回值

5.2. 字符串不可修改性

5.3. 字符和字符串的比较

5.4. 字符串终止符

5.5. 缓冲区溢出

5.6. 线程安全性

5.7. 性能考虑

5.8. 兼容性

六、使用示例

6.1.strchr 使用示例

6.2. strrchr 使用示例

6.3 strstr 使用示例


在C语言中,处理字符串时经常会用到一些标准库函数来查找或操作字符串。strchrstrrchrstrstr是三个非常有用的字符串查找函数,它们分别用于不同的查找目的。它们的函数原型均定义在 <string.h> 头文件中。

一、函数简介

1.1. strchr 函数

strchr 函数用于在字符串中查找第一次出现的指定字符。

1.2. strrchr函数

strchr相似,但strrchr是从字符串的末尾开始向前查找第一次出现的指定字符。

1.3. strstr 函数

strstr用于在字符串中查找第一次出现的子串。

二、函数原型

2.1. strchr 函数

char *strchr(const char *str, int c);

参数

  • str:指向要搜索的字符串的指针。
  • c:要搜索的字符,尽管参数类型是 int,但函数实际上会将其视为 unsigned char 并与字符串中的字符进行比较。

返回值

  • 如果找到字符 c,则返回指向该字符在字符串中第一次出现位置的指针。
  • 如果未找到字符 c,则返回 NULL 指针。

2.1. strchr 函数

char *strrchr(const char *str, int c);

参数

  • str:指向要搜索的字符串的指针。
  • c:要搜索的字符,尽管参数类型是 int,但函数实际上会将其视为 unsigned char 并与字符串中的字符进行比较。

返回值

  • 如果找到字符 c,则返回指向该字符在字符串中最后一次出现位置的指针。
  • 如果未找到字符 c,则返回 NULL 指针。

2.2. strstr 函数

char *strstr(const char *str1, const char *str2);

参数

  • str1:指向要搜索的字符串(主串)的指针。
  • str2:指向要搜索的子串的指针。

返回值

  • 如果找到子串 str2,则返回指向 str1 中 str2 首次出现位置的指针。返回的指针指向 str1 中子串 str2 的开始位置。
  • 如果未找到子串 str2,则返回 NULL 指针。

三、函数实现(伪代码)

在 C 语言中,strchrstrrchr和 strstr 是标准库函数,它们通常通过优化算法在底层实现,以提高性能。然而,为了教学目的,我们可以尝试用简单的循环来模拟这些函数的实现。请注意,这些实现可能不是最高效的,但它们清晰地展示了这些函数的基本工作原理。

3.1. strchr 实现

#include <stdio.h>  
  
char *my_strchr(const char *str, int c) {  
    while (*str != '\0') { // 遍历字符串直到结束符  
        if ((unsigned char)*str == (unsigned char)c) { // 比较字符(考虑类型转换)  
            return (char *)str; // 找到字符,返回当前位置的指针  
        }  
        str++; // 移动到下一个字符  
    }  
    return NULL; // 未找到字符,返回NULL  
}  
  
int main() {  
    char str[] = "Hello, World!";  
    char *ptr = my_strchr(str, 'W');  
    if (ptr != NULL) {  
        printf("Found 'W' at position: %ld\n", ptr - str);  
    } else {  
        printf("'W' not found.\n");  
    }  
    return 0;  
}

3.2. strrchr 实现

#include <stdio.h>  
  
char *my_strrchr(const char *str, int c) {  
    const char *last_occurrence = NULL; // 用于记录最后一次出现的位置  
    while (*str != '\0') { // 遍历字符串直到结束符  
        if ((unsigned char)*str == (unsigned char)c) { // 比较字符  
            last_occurrence = str; // 更新最后一次出现的位置  
        }  
        str++; // 移动到下一个字符  
    }  
    return (char *)last_occurrence; // 返回最后一次出现的位置或NULL  
}  
  
int main() {  
    char str[] = "Hello, World!";  
    char *ptr = my_strrchr(str, 'o');  
    if (ptr != NULL) {  
        printf("Found 'o' (last occurrence) at position: %ld\n", ptr - str);  
    } else {  
        printf("'o' not found.\n");  
    }  
    return 0;  
}

3.3. strstr 实现

#include <stdio.h>  
  
char *my_strstr(const char *str1, const char *str2) {  
    if (!*str2) { // 如果str2是空字符串,则返回str1的起始位置  
        return (char *)str1;  
    }  
  
    const char *p1, *p2, *p1_start;  
    p1 = str1;  
    p2 = str2;  
  
    while (*p1 != '\0') { // 遍历str1  
        p1_start = p1; // 记录当前遍历的起始位置  
  
        while (*p1_start == *p2 && *p2 != '\0') { // 逐个字符比较  
            p1_start++;  
            p2++;  
        }  
  
        if (!*p2) { // 如果p2已经到达末尾,说明找到了子串  
            return (char *)p1;  
        }  
  
        p2 = str2; // 重置p2到str2的起始位置  
        p1++; // 移动p1到下一个字符  
    }  
  
    return NULL; // 未找到子串  
}  
  
int main() {  
    char str[] = "Hello, World of Programming!";  
    char *substr = "World";  
    char *ptr = my_strstr(str, substr);  
    if (ptr != NULL) {  
        printf("'%s' found at position: %ld\n", substr, ptr - str);  
    } else {  
        printf("'%s' not found.\n", substr);  
    }  
    return 0;  
}

这些实现提供了对 strchrstrrchr, 和 strstr 函数工作原理的基本理解。然而,在实际应用中,应该使用标准库提供的这些函数,因为它们经过了优化,可以提供更好的性能。

四、使用场景

在C语言中,strchrstrrchr和 strstr 这三个字符串处理函数各有其特定的使用场景,它们主要用于在字符串中查找字符或子串。下面是它们各自的使用场景。

4.1.strchr 使用场景

  • 当需要在字符串中查找某个特定字符的第一次出现时,可以使用 strchr
  • 例如,想从一个包含用户输入的字符串中查找第一个空格字符,以便分割字符串或进行其他处理。
  • 另一个例子是,在处理文件名或路径时,想找到最后一个点(.)字符的位置,以确定文件扩展名。

4.2.strrchr 使用场景

  • 当需要在字符串中查找某个特定字符的最后一次出现时,strrchr 是合适的选择。
  • 这在处理文件路径时特别有用,比如想找到最后一个目录分隔符(在Unix/Linux中是/,在Windows中是\/),以确定文件名或最后一级目录名。
  • 另一个例子是,在解析一个由逗号分隔的列表时,想找到最后一个逗号的位置,以获取最后一个元素。

4.3. strstr 使用场景

  • 当需要在字符串中查找一个子串的第一次出现时,strstr 是必需的。
  • 在解析包含多个字段的文本数据(如CSV文件、日志条目或HTML标记)时非常有用。
  • 另一个常见的使用场景是在用户输入中查找特定的命令或关键字,以确定用户的意图或执行特定的操作。
  • 在网络编程中,strstr 可以用于在HTTP请求或响应中查找特定的头部字段或值。

五、注意事项

在C语言中,使用strchrstrrchrstrstr等字符串处理函数时,需要注意以下几点以确保代码的健壮性和正确性。

5.1. 检查返回值

  • 这些函数在找到匹配项时返回一个指向匹配项起始位置的指针,如果未找到匹配项,则返回NULL。因此,在使用这些函数的返回值之前,必须检查它们是否为NULL,以避免空指针解引用错误。

5.2. 字符串不可修改性

  • 这些函数返回的指针指向原始字符串中的位置。如果原始字符串是通过字面量或只读内存区域(如字符串常量)创建的,则不应通过返回的指针修改字符串内容。修改这样的字符串是未定义行为,可能导致程序崩溃或数据损坏。

5.3. 字符和字符串的比较

  • strchrstrrchr函数查找的是单个字符,而strstr查找的是子串。在调用这些函数时,请确保传递了正确的参数类型(字符或字符串)。
  • 字符比较是区分大小写的,除非字符串以某种方式被转换为统一的大小写形式。如果需要不区分大小写的比较,请自行实现或使用其他库函数。

5.4. 字符串终止符

  • 这些函数都依赖于字符串的终止符('\0')来确定字符串的结束。确保传递给这些函数的字符串是正确终止的,否则它们可能会继续读取内存直到遇到随机出现的终止符,导致未定义行为。

5.5. 缓冲区溢出

  • 虽然这些函数本身不会导致缓冲区溢出,但它们的返回值可能会被用于索引或操作字符串的其他部分。在使用这些返回值进行索引或操作时,请确保不会超出原始字符串的边界,以避免潜在的缓冲区溢出问题。

5.6. 线程安全性

  • 标准C库中的strchrstrrchrstrstr函数通常不是线程安全的。如果多个线程可能会同时修改或访问这些函数所使用的字符串,则需要采取适当的同步措施来避免数据竞争和条件竞争。

5.7. 性能考虑

  • 在处理非常长的字符串或需要频繁调用这些函数的场景中,应注意它们的性能影响。虽然这些函数通常足够快,但在极端情况下,可能需要考虑使用更高效的算法或数据结构来优化性能。

5.8. 兼容性

  • 尽管这些函数在大多数C标准库中都是可用的,但最好检查你正在使用的特定编译器或库文档,以确保它们的可用性和行为符合预期。

六、使用示例

以下是C语言中strchrstrrchrstrstr函数的使用示例。这些示例展示了如何在不同的场景中使用这些函数来查找字符串中的字符或子串。

6.1.strchr 使用示例

#include <stdio.h>  
  
int main() {  
    const char *str = "Hello, World!";  
    char c = 'W';  
      
    // 查找字符'W'  
    char *found = strchr(str, c);  
      
    if (found != NULL) {  
        printf("Found '%c' at position: %ld\n", c, found - str);  
    } else {  
        printf("'%c' not found.\n", c);  
    }  
      
    return 0;  
}

6.2. strrchr 使用示例

#include <stdio.h>  
  
int main() {  
    const char *str = "Hello, World!";  
    char c = 'o';  
      
    // 查找字符'o'的最后一次出现  
    char *found = strrchr(str, c);  
      
    if (found != NULL) {  
        printf("Found '%c' (last occurrence) at position: %ld\n", c, found - str);  
    } else {  
        printf("'%c' not found.\n", c);  
    }  
      
    return 0;  
}

6.3 strstr 使用示例

#include <stdio.h>  
  
int main() {  
    const char *str = "Hello, this is a test string.";  
    const char *substr = "test";  
      
    // 查找子串"test"  
    char *found = strstr(str, substr);  
      
    if (found != NULL) {  
        printf("Found '%s' at position: %ld\n", substr, found - str);  
    } else {  
        printf("'%s' not found.\n", substr);  
    }  
      
    return 0;  
}

在这些示例中,我们使用了strchr来查找字符串中特定字符的第一次出现,strrchr来查找特定字符的最后一次出现,以及strstr来查找子串的第一次出现。每个函数都返回一个指向找到的字符或子串的起始位置的指针,如果未找到,则返回NULL。我们使用found - str来计算找到的字符或子串在原始字符串中的位置(基于0的索引)。

请注意,由于字符串在C语言中是以字符数组的形式存储的,并且以空字符('\0')结尾,因此可以通过指针运算来计算字符或子串在字符串中的位置。此外,示例中的字符串是通过const char *类型声明的,表示这些字符串是不可修改的。如果原始字符串不是通过字面量或只读内存区域创建的,并且你需要在找到的位置修改字符串,那么你应该使用char *类型来声明原始字符串。但是,请务必确保你有权修改该字符串,并且不会破坏其以空字符结尾的特性。

标签:strchr,字符,strstr,char,str,字符串,strrchr
From: https://blog.csdn.net/weixin_37800531/article/details/141982323

相关文章

  • 华为OD机试真题-增强的strstr-2024年OD统一考试(E卷)
     题目描述C语言有一个库函数Q:char*strstr(constchar*haystack,constchar*needle),实现在字符串haystack中查找第一次出现字符串needle的位置,如果未找到则返回null。现要求实现一个strstr的增强函数,可以使用带可选段的字符串来模糊査询,与strstr一样返回首次查找......
  • day9第四章 字符串part02| 151.翻转字符串里的单词 |卡码网:55.右旋转字符串|28. 实现
    151.翻转字符串里的单词classSolution{publicStringreverseWords(Strings){////删除首尾空格,分割字符串String[]str=s.trim().split("");StringBuildersb=newStringBuilder();////倒序遍历单词列表for(inti......
  • 实现strStr() —— KMP算法(包含next数组的优化)
    目录KMP算法KMP算法的应用前缀表最长公共前后缀为什么要使用前缀表如何计算前缀表前缀表和next数组时间复杂度分析例题28.实现strStr构造next数组 使用next数组来做匹配 前缀表统一减一C++代码实现前缀表(不减一)C++代码实现总结 拓展:next数组的优化 KMP算......
  • 代码随想录算法训练营day09|151.翻转字符串里的单词,卡码网:55.右旋转字符串,28.实现 str
    151.翻转字符串里的单词题目链接:https://leetcode.cn/problems/reverse-words-in-a-string/description/暴力removeExtraSpaces:voidremoveExtraSpaces(string&s){for(inti=s.size()-1;i>0;i--){if(s[i]==''&&s[i]=......
  • 每天深解一个字符串类函数之strstr函数
    目录前言:一、引用头文件二、strstr函数的作用三、理解strstr函数的定义1、返回类型2、参数 四、使用strstr函数1、编写程序2、调试运行五、注意要点 六、模拟实现前言:每天深入了解一个字符串类函数,今天我们要学习的是strstr函数,相信你学玩之后会对字符串......
  • 字符串查找 - 模拟实现strstr 、BF算法 、 KMP算法
    文章目录前言一、模拟实现库函数strstr二、BF算法三、KMP算法总结前言路漫漫其修远兮,吾将上下而求索。一、模拟实现库函数strstrTips:此处采用利用指针+字符串末尾'\0'的判断,当然你可以利用数组的下标;库函数strstr的原型:char*strstr(constchar*str1,......
  • 常见 字符串库函数 的使用与模拟实现 #strlen #strcpy #strcat #strcmp#strstr #strto
    文章目录前言路漫漫其修远兮,吾将上下而求索。在C语言之中,提供了字符类型,也有字符串的概念,但是却并没有字符串的类型。没有类型就不方便操作,于是乎就提供了一系列的字符串函数来支持对字符串的操作;一、求字符串长度strlen专门用来求字符串长度的函数size_t strl......
  • 模拟实现 strstr(字符串查找) --浅谈C语言
    C字符串查找-strstr()描述C库函数char*strstr(constchar*haystack,constchar*needle)在字符串haystack中查找第一次出现字符串needle的位置,不包含终止符'\0'。声明下面是strstr()函数的声明。char*strstr(constchar*haystack,constchar*needle)参......
  • /*使用strchr(),strrchr(),strpdrk()函数*/
    /使用strchr(),strrchr(),strpdrk()函数/#include<stdio.h>#include<string.h>/使用strchr()函数:如果s字符串中包含c字符,该函数返回指向s字符串首次出现c字符的指针,未找到返回NULL/voidstr_chr(constchar*s,intc){if(strchr(s,c)!=NULL){printf......
  • 代码随想录算法训练营第九天 | 151.翻转字符串里的单词,卡码网:55.右旋转字符串,28. 实现
    151.翻转字符串里的单词题目链接:力扣题目链接文章讲解:代码随想录 视频讲解:字符串复杂操作拿捏了!|LeetCode:151.翻转字符串里的单词思路这道题目可以说是综合考察了字符串的多种操作。其实这道题和反转字符串这道题目很像,而且用法也是通用的方法一:切片,reverse,以及......