strstr(str1,str2) 函数

本文深入解析strstr函数的使用方法及注意事项,特别是在字符串处理和截取中的应用。通过实例说明,如何避免因不当操作导致的错误,如在使用strstr返回值前修改原字符串,导致结果异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可能有的人还没听过strstr函数,个人认为这个一个很实用的函数,strstr(str1,str2) 函数是字符串处理函数之一,位于头文件 “string.h”中。对于处理字符串的一些问题有很大的帮助。


定义:strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。

源于百度百科:

http://baike.baidu.com/link?url=ya28ba45_Sr6cFdJfNiQdHXl2jpZ_miXq-XnVOZurxXP_BEAck-q6ut3gX7X-cVe15lfkAWCv8z2dZQTi28VBa

定义说的有点羞涩难懂。举个例子就知道了。 
比如: 
char str2 = “cdef”; 
char str1 = “abcdefgh”; 
则通过函数,将返回 
strstr(str1,str2) = cdefgh;

如果str1不包含有str2。 
char str2 = “cxef”; 
char str1 = “abcdefgh”; 
则通过函数,将返回 
strstr(str1,str2) = NULL;


该函数在比较字符串和对字符串的截取上有很大的帮助。但在某次使用过程中,程序出现了无法预料的错误。通过分析并打印显示出strstr的返回值,才发现问题出在该函数上。 
情况描述: 
函数功能是,判断出数组字符串里的Uart2_Buf 含有“START”字符串的情况下,将截取其返回值给Mystr。然后把Uart2_Buf 内容清空,并打印出Mystr。

        char Uart2_Buf[11] = "abSTARTdend;
        char Mystr1[20] = {0};
        char *Mystr=Mystr1;

        //提取出Mystr
        void test_strstr()
        {
            if(strstr(Uart2_Buf , "START") != NULL)
            {
                Mystr = strstr(Uart2_Buf , "START");//返回START即之后的值
                CLR_Buf2();//把Uart2_Buf 内容清空
                printf("Mystr=%s ",Mystr);
            }
        }
        //清空Uart2_Buf 
        void CLR_Buf2(void)
        {
            u16 k;

                for(k=0;k<11;k++)      
                {
                    Uart2_Buf[k] = 0X00;
                }

        }

结果: 
上位机打印出显示:Mystr= 
Mystr为空,没有任何东西。

通过调试,去掉函数里CLR_Buf2(); 不对Uart2_Buf 进行清空,再打印显示:Mystr=STARTdend

这样就能确定错误的结果跟清空Uart2_Buf 有关了,辣么,如果不是清空Uart2_Buf ,而是给Uart2_Buf 赋值呢? 
更改函数:void CLR_Buf2(void)

        //Uart2_Buf 赋值'a'
        void CLR_Buf2(void)
        {
            u16 k;

                for(k=0;k<11;k++)      
                {
                    Uart2_Buf[k] = 'a';
                }

        }

结果: 
上位机打印出显示:Mystr=aaaaaaaaa(9个a) 
居然显示的是Uart2_Buf 的后部分(Uart2_Buf长度为20),按正常应该显示的是9个字符“STARTdend“才对。

通过其他测试,只要在对Mystr显示之前,更改了Uart2_Buf的内容,那么显示结果就会错误,而且Mystr显示的是Uart2_Buf更改的后部分的值。 
因此可以推断出,Mystr的显示和Uart2_Buf 地址有关,或者Mystr显示跟相关指针有关


那么一定是对该函数的使用方法用错了,或者还没完全理解其定义。再回到这个函数定义,仔细阅读这句: 
定义:strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。


瞬间明白了原先觉得羞涩难懂的定义,原来strstr(str1,str2)返回的是str2在str1中首次出现的地址,也就是说,strstr(str1,str2)返回值能随str1变化而变化,因为他们内容有共用地址,地址一样,输出的内容也一样。


结论(注意事项):

因而,在使用或者处理strstr(str1,str2)返回值之前,切记不要对str1字符串进行更改,若要更改,应该等使用完返回值后再更改!! 

### 关于 `strstr` 函数的用法和实现 在C/C++标准库中,`strstr` 是一个用于字符串操作的重要函数。它被定义在 `<string.h>` 或 `<cstring>` 头文件中,其功能是从源字符串中查找指定子串的第一个匹配位置。 #### 函数原型 以下是 `strstr` 的函数声明: ```c char *strstr(const char *haystack, const char *needle); ``` - 参数说明: - `haystack`: 被搜索的目标字符串。 - `needle`: 需要查找的子字符串。 - 返回值: 如果找到子串,则返回指向第一次出现该子串的位置;如果未找到或者 `needle` 为空字符串,则返回 NULL[^3]。 #### 实现原理 为了更好地理解 `strstr` 的工作方式,可以手动实现它的逻辑如下: ```c #include <stdio.h> #include <stdlib.h> // 自定义 strstr 函数 char* custom_strstr(const char* haystack, const char* needle) { if (*needle == '\0') { // 子串为空的情况 return (char*)haystack; } while (*haystack != '\0') { const char* h = haystack; // 当前字符指针 const char* n = needle; while (*h == *n && *n != '\0') { // 比较两个字符是否相等 ++h; ++n; } if (*n == '\0') { // 找到完全匹配的子串 return (char*)haystack; } ++haystack; // 移动到下一个字符继续比较 } return NULL; // 若无匹配项则返回NULL } ``` 上述代码展示了如何通过逐字对比来寻找目标子串的过程。当遇到第一个不一致的字符时会跳过当前起始点并重新开始下一轮扫描直到遍历整个主字符串为止[^4]。 #### 使用示例 下面是一个简单的例子展示如何调用原生以及自定义版本的 `strstr` 方法: ```c int main() { const char str[] = "This is a simple example."; const char subStr[] = "simple"; printf("Using standard strstr(): %s\n", strstr(str, subStr)); printf("Using custom strstr(): %s\n", custom_strstr(str, subStr)); return EXIT_SUCCESS; } ``` 运行此程序将会打印出首次发现 `"simple"` 这个单词所在地址处的内容片段[^5]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值