如何在给定的C语言子串匹配代码中正确使用gets()函数?
在子字符串匹配代码中使用
gets()的说明与代码补全 首先必须严肃提醒:gets()函数存在严重的缓冲区溢出风险——它不会检查输入的字符长度,一旦用户输入的内容超过数组定义的大小,就会破坏内存区域,导致程序崩溃甚至引发安全漏洞。虽然你要求使用gets(),但还是建议后续开发中用更安全的fgets()替代。
接下来我们补全你提供的不完整代码,并详细说明gets()的使用(以及代码逻辑的完善):
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { int count, i, j; char str[50], sub_str[50]; // 使用gets()读取主字符串 printf("Enter the main string : "); gets(str); // 使用gets()读取子字符串 printf("Enter the sub string : "); gets(sub_str); printf("Main string: %s\nSub string: %s\n", str, sub_str); int l_str = strlen(str); int l_sub_str = strlen(sub_str); int match_found = 0; // 标记是否找到匹配 // 处理子字符串为空的特殊情况 if (l_sub_str == 0) { printf("Sub string cannot be empty.\n"); return 1; } // 优化循环边界,避免数组越界访问 for(i = 0; i <= l_str - l_sub_str; i++) { if(str[i] == sub_str[0]) { count = 0; // 重置匹配计数 for(j = 0; j < l_sub_str; j++) { if(str[i+j] == sub_str[j]) { count++; } else { break; // 有字符不匹配,跳出内层循环 } } // 若所有字符都匹配,说明找到子串 if(count == l_sub_str) { printf("Sub string found at index: %d\n", i); match_found = 1; // 如果只需要找第一个匹配,可在这里加return 0; } } } if(!match_found) { printf("Sub string not found in main string.\n"); } return 0; }
关于gets()的使用细节
- 语法正确用法:
gets()会从标准输入读取一行文本(直到遇到换行符),自动将换行符替换为字符串结束符\0,然后存储到传入的字符数组中。你代码里的gets(str)和gets(sub_str)是语法上的正确使用方式,但安全隐患极大。 - 核心风险点:如果用户输入的字符数超过数组定义的50个(比如输入60个字符),
gets()会直接写入数组外的内存区域,触发缓冲区溢出,这是生产环境中绝对要避免的问题。
代码逻辑的完善说明
- 优化循环边界:原代码
i < l_str会导致i+j超出主字符串的内存范围,改成i <= l_str - l_sub_str可以彻底避免越界访问。 - 修复匹配计数逻辑:原代码中
count初始值为1,容易导致匹配判断错误,现在重置为0,每匹配一个字符加1,当count等于子字符串长度时,即可确认完全匹配。 - 添加结果标记:新增
match_found变量,处理子字符串未找到的场景,同时补充了子字符串为空的特殊情况判断。
安全替代方案(强烈推荐)
用fgets()替代gets(),它可以指定最大读取字符数,从根源上避免缓冲区溢出:
// 读取主字符串,限制最多读取49个字符(留一个位置存\0) fgets(str, sizeof(str), stdin); // 手动去掉fgets读取到的换行符 str[strcspn(str, "\n")] = '\0'; // 读取子字符串同理 fgets(sub_str, sizeof(sub_str), stdin); sub_str[strcspn(sub_str, "\n")] = '\0';
内容的提问来源于stack exchange,提问作者Aditya Trivedi
相关产品推荐
相关产品推荐

