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

使用fgets获取字符串后在单词间插入#时出现访问越界错误

问题排查与修复

错误原因

导致访问违例的核心问题有4个:

  • replaceChar 函数的循环条件存在严重类型错误:current_pos + strlen(current_pos) 是内存地址,直接和字符常量'\n'比较逻辑完全失效,无法阻止内存越界访问。
  • strtok 切割字符串时会将所有分隔符(空格)替换为'\0',你调用replaceChar全局替换'\0'为'#'时,会把字符串末尾的终止符'\0'也替换掉,导致字符串没有结束标识。后续strchr会持续向后读取超出合法边界的内存,直接触发访问违例。
  • replaceChar 每次都从字符串开头调用strchr查找目标字符,替换后仍然从头查找,不仅效率极低,在丢失字符串终止符后会无限遍历非法内存。
  • 原有逻辑无法满足需求:如果原字符串存在连续空格,strtok会生成多个连续'\0',全部替换为'#'会出现连续#,不符合「单词之间插入单个#」的要求。

修复方案

以下是可直接使用的原地修改实现,自动处理开头空格、结尾空格、连续空格场景,不会触发内存越界:

// 调用前先处理fgets读取的换行符
char buf[1024];
fgets(buf, sizeof(buf), stdin);
buf[strcspn(buf, "\n")] = '\0'; // 移除末尾换行符

// 插入#的核心函数
char* addNumberSign(char* string) {
    if (string == NULL || *string == '\0') return string;
    char* write_ptr = string;
    char* read_ptr = string;

    // 跳过开头所有空格
    while (*read_ptr == ' ') read_ptr++;

    while (*read_ptr != '\0') {
        // 复制当前完整单词
        while (*read_ptr != ' ' && *read_ptr != '\0') {
            *write_ptr++ = *read_ptr++;
        }
        // 跳过当前单词后的所有连续空格
        while (*read_ptr == ' ') read_ptr++;
        // 还有后续单词则插入#
        if (*read_ptr != '\0') {
            *write_ptr++ = '#';
        }
    }
    // 补字符串终止符
    *write_ptr = '\0';
    return string;
}

如果你坚持要基于strtok实现,需要预先记录所有单词的位置,再手动插入#,不能直接全局替换'\0'。

内容的提问来源于stack exchange,提问作者Roee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:06:04