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

C语言scanf()无法读取整行 开启地址消毒器报heap-buffer-overflow错误

问题根因

1. 输入读取逻辑错误

你使用scanf("%s", text)读取输入,%s格式符默认遇到空格就终止读取,如果你输入带空格的内容(比如he3llo world),实际上只有空格前的he3llo会被存入text,后面的内容直接被丢弃,这就是你输出结果只有hello的直接原因。

2. 输出字符串缺少空终止符

C语言的字符串必须以'\0'作为结束标记,你在fix_text函数中往fixed_message写入所有过滤后的字符后,没有手动在末尾追加'\0',printf输出字符串时会持续越界读取堆内存,直到碰到随机的'\0'才停止,这就是AddressSanitizer抛出heap-buffer-overflow异常的核心原因。

3. 过滤逻辑和预期不匹配

你当前的代码仅保留字母字符,数字、空格都会被直接过滤,如果你需要保留数字、空格,需要调整判断分支。


修复方案

调整后代码

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char* fix_text(char* data, int len)
{
    char* fixed_message = malloc (len * sizeof(char));
    int offset = 0;
    for (int i = 0; i < len; i++)
    {
        if(data[i] == '\0')
        {
            break;
        }
        // 这里调整过滤规则,按需修改:当前逻辑是保留字母、数字、空格,其余过滤
        if (isalpha(data[i]) || isdigit(data[i]) || data[i] == ' ')
        {
            fixed_message[offset] = data[i];
            offset++; 
        }
    }
    // 追加字符串结束标记
    fixed_message[offset] = '\0';
    return fixed_message;
}
int main()
{
    char * text = malloc(100 * sizeof(char));
    // 读取整行输入(含空格),限制最多读99个字符,避免溢出
    scanf("%99[^\n]", text);
    char* result = fix_text(text, 100);
    printf("%s\n", result);
    free(text);
    free(result);
    return 0;
}

额外说明

如果你的需求是仅保留字母,去掉所有数字、空格,只需要把fix_text里的过滤条件改回isalpha(data[i])即可,输出结果就会是你预期的helloworld。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 17:24:00