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

C语言多子串替换问题求助:将指定子串替换为星号

解决多子串替换为星号的C程序问题

你好!我看了你的代码,确实在多子串替换的实现上有几个需要调整的地方,我先梳理问题点,再给你修正后的完整实现:

现有代码的核心问题

  • 不安全的gets()函数:gets()完全不检查输入长度,很容易造成缓冲区溢出,强烈建议用fgets()替代,同时要处理输入末尾的换行符。
  • 变长数组顺序错误:第二个版本里你先定义了char substr[n][100];,但此时n还没赋值,这不符合C标准(变长数组的大小必须是已经确定的变量),得先读n再定义数组。
  • 变量名笔误:代码里的cuv[i]是拼写错误,应该是substr[i]。
  • 仅替换第一个匹配项:现有代码用strstr()只找得到第一个匹配的子串,不会处理字符串中重复出现的同一子串。
  • 输入缓冲区残留问题:scanf("%d", &n)执行后,输入缓冲区会留下换行符,导致后续读取子串时可能直接读到空内容。

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    char str[5120];
    int n;

    // 读取初始字符串,替换不安全的gets()
    printf("Type the string:\n");
    if (fgets(str, sizeof(str), stdin) == NULL) {
        fprintf(stderr, "Failed to read string\n");
        return 1;
    }
    // 去掉fgets读取的换行符(如果存在)
    str[strcspn(str, "\n")] = '\0';

    // 读取待修改子串的数量
    printf("How many substrings to modify? ");
    if (scanf("%d", &n) != 1 || n <= 0) {
        fprintf(stderr, "Invalid number of substrings\n");
        return 1;
    }
    // 清除scanf后残留的换行符,避免影响后续输入
    while (getchar() != '\n');

    // 定义子串数组(现在n已经赋值,变长数组合法)
    char substr[n][100];

    // 读取所有待修改子串
    printf("\nType the substrings (each up to 99 characters):\n");
    for (int i = 0; i < n; i++) {
        printf("Substring %d: ", i + 1);
        if (fgets(substr[i], sizeof(substr[i]), stdin) == NULL) {
            fprintf(stderr, "Failed to read substring %d\n", i + 1);
            return 1;
        }
        // 去掉子串的换行符
        substr[i][strcspn(substr[i], "\n")] = '\0';
        // 检查子串是否为空
        if (strlen(substr[i]) == 0) {
            fprintf(stderr, "Substring %d cannot be empty\n", i + 1);
            return 1;
        }
    }

    // 处理每个子串的替换(替换所有出现的匹配项)
    for (int i = 0; i < n; i++) {
        const char *sub = substr[i];
        size_t sub_len = strlen(sub);
        char *pos = str;

        // 循环查找所有匹配的子串,直到找不到为止
        while ((pos = strstr(pos, sub)) != NULL) {
            // 将匹配到的子串替换为*
            memset(pos, '*', sub_len);
            // 移动指针,避免重复替换同一位置(比如子串是"aa",替换后变成"**",不会再匹配)
            pos += sub_len;
        }
    }

    // 输出修改后的字符串
    printf("\nThe modified string is:\n%s\n", str);

    return 0;
}

关键改进说明

  1. 安全输入处理:用fgets()替代gets(),并通过strcspn()自动去掉输入末尾的换行符,避免字符串里带多余的换行。
  2. 正确的变长数组使用:先读取n的值,再定义substr[n][100],符合C标准对变长数组的要求。
  3. 替换所有匹配项:通过while循环反复调用strstr(),直到找不到子串为止,确保所有出现的目标子串都被替换成*。
  4. 输入缓冲区清理:在scanf("%d", &n)后,用while (getchar() != '\n')清空残留的换行符,避免后续fgets()读到空内容。
  5. 基础错误处理:增加了输入失败的判断,比如读取字符串或子串失败时给出错误提示,让程序更健壮。

额外小提示

如果你需要支持更复杂的场景(比如大小写不敏感匹配、重叠子串处理),可以自己实现自定义的匹配函数替代strstr()。另外,如果初始字符串可能超过5120字节,可以考虑用malloc()动态分配内存,避免栈溢出。

内容的提问来源于stack exchange,提问作者Saledin Mert Aykut

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:07:50