You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在给定的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()会直接写入数组外的内存区域,触发缓冲区溢出,这是生产环境中绝对要避免的问题。

代码逻辑的完善说明

  1. 优化循环边界:原代码i < l_str会导致i+j超出主字符串的内存范围,改成i <= l_str - l_sub_str可以彻底避免越界访问。
  2. 修复匹配计数逻辑:原代码中count初始值为1,容易导致匹配判断错误,现在重置为0,每匹配一个字符加1,当count等于子字符串长度时,即可确认完全匹配。
  3. 添加结果标记:新增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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:34:40