strstr函数匹配长度小于3的needle时失效问题排查
问题分析:字符串查找子串的异常原因
原代码
#include <stdio.h> #include <stdlib.h> #include <string.h> char* findSequence(char s[], char ch, int n){ int i; char*ptr; char needle[n]; char*npdr=&needle; for(i=0;i<n;i++){needle[i]=ch;} ptr = strstr(s,ndpr); // 存在笔误:ndpr应为npdr printf("%s",ptr); return ptr; } int main() { char stringa[]={"ciccciopasticcio"}; char carattere='c'; char*ptr; int n=3; ptr=findSequence(stringa, carattere,n); return 0; }
问题描述
这段代码用于在字符串中查找由指定字符重复n次组成的子串,当n≥3时运行正常,但n为1或2时出现异常。调试发现指针npdr指向的needle会额外出现随机字符,例如n=2时,needle本应为"cc",实际却为"cc@"。
问题原因
核心问题是C语言的字符串必须以'\0'(空字符)作为结束标志,strstr这类标准字符串处理函数完全依赖这个标志来判断字符串的边界:
- 你定义的
char needle[n]是长度为n的字符数组,循环里只填充了n个目标字符,但没有手动添加结尾的'\0'。 - 当n≥3时,数组后面的内存碰巧是
'\0'(未初始化内存的随机值,纯属运气),所以strstr能正确识别needle的长度;但n=1或2时,数组后面的内存是随机垃圾字符(比如你看到的'@'),导致needle被当成了更长的无效字符串,strstr自然无法正确匹配目标子串,出现异常。 - 代码里还存在笔误:
strstr的第二个参数写成了ndpr,实际应为npdr,不过这属于输入手误,不是核心问题。
修复方法
给needle预留结束符的位置,并手动添加'\0'即可:
char* findSequence(char s[], char ch, int n){ int i; char*ptr; char needle[n+1]; // 多留一个位置存'\0' char*npdr=needle; // 数组名本身就是指针,无需取地址 for(i=0;i<n;i++){ needle[i]=ch; } needle[n] = '\0'; // 手动添加字符串结束符 ptr = strstr(s, npdr); printf("%s",ptr); return ptr; }
内容的提问来源于stack exchange,提问作者Tarkov Account
相关产品推荐
相关产品推荐

