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
相关产品推荐
相关产品推荐

