C语言scanf读取用户输入时字符串打印显示异常问题
故障原因
核心问题是存储用户输入的字符数组空间分配不足,触发栈内存越界写入,属于C语言典型的未定义行为:
- 你用
char inputRoses[] = "";这种写法定义输入缓冲区时,编译器会根据初始化值(空字符串)自动计算数组长度:空字符串仅包含1个字符串结束符\0,因此数组实际分配长度只有1字节,完全无法存储任何有效用户输入。 scanf("%s", 地址)读取字符串时,不会检查目标缓冲区的可用长度,会把用户输入的字符+末尾结束符依次从目标起始地址开始写入。比如你输入red,实际会写入r/e/d/\0共4字节,远超1字节的缓冲区大小,多出来的内容会直接覆盖栈上相邻位置存储的其他局部变量(比如你定义的violets、roses这些固定字符串的内存)。- 你看到的输出末尾多出的
ue/ed,就是原本要打印的提示字符串被输入内容覆盖后,打印出的内存残留片段。
额外注意:代码里用and作为变量名属于不规范写法,and是C标准中定义的替代&&逻辑运算符的宏,部分编译环境下会直接报错。
修复方案
- 给所有用于存储用户输入的字符数组提前分配足够的固定长度,比如预留100字节应对普通短输入,定义时初始化全0避免垃圾值干扰,写法为
char inputRoses[100] = {0};,其余输入数组同理修改。 - 调用
scanf读字符串时,在格式符里加长度限制,预留1字节给字符串结束符,避免用户输入过长再次触发越界,比如读100字节长度的缓冲区时,写为scanf("%99s", inputRoses);。 - 把原代码里的
and变量名改成其他合法标识符,比如and_tip,避免和标准宏冲突。
修复后的可运行代码示例:
#include <stdio.h> int main() { // 预分配100字节输入缓冲区,初始化全0 char inputRoses[100] = {0}; char inputViolets[100] = {0}; char inputAnd[100] = {0}; char roses[] = "Roses are: "; char violets[] = "Violets are: "; char and_tip[] = "and: "; printf("\n%s", roses); scanf("%99s", inputRoses); printf("\n%s", violets); scanf("%99s", inputViolets); printf("\n%s", and_tip); scanf("%99s", inputAnd); // 如果需要输出完整拼接结果,可取消下一行注释 // printf("\nRoses are %s\nViolets are %s\n%s %s\n", inputRoses, inputViolets, and_tip, inputAnd); return 0; }
内容的提问来源于stack exchange,提问作者mrk123
相关产品推荐
相关产品推荐

