C语言scanf格式符问题:输入1 * 2输出异常原因排查
问题原因分析与修正
核心异常原因:scanf格式串的内存越界错误
你的代码中scanf("%d%2c%f", &op1, &op, &op2);的%2c是错误用法:
%2c表示要读取最多2个字符,但op是char类型,仅占1字节内存。scanf会尝试向op的内存地址写入2个字节的数据,直接触发内存越界,覆盖了相邻变量op1的内容。- 当你输入
1 * 2时,%d先读取整数1存入op1,紧接着%2c会读取输入中1之后的两个字符:空格(ASCII码32)和*(ASCII码42)。由于op只能存1个字节,第一个字符空格被存入op,第二个字符*会意外写入op1的内存区域,将原本的1修改为32,这就是输出中op1变成32的直接原因。
额外格式问题(不符合预期输出的原因)
即使修复内存越界,原代码的输入输出逻辑也和你的预期不符:
- 输入阶段:
%d和%c之间没有空白符,输入中的空格会被%c直接读取,而不是跳过,导致op存的是空格而非*。 - 输出阶段:
%2c会让字符以2个宽度右对齐输出(比如*会变成*),%f默认输出6位小数,和你预期的1* 2格式不匹配。
修正后的代码示例
#include <stdio.h> int main() { int op1; char op; float op2; // 用空格跳过输入中的空白符,%c仅读取单个运算符 scanf("%d %c %f", &op1, &op, &op2); // 按预期格式输出,%.1f控制小数位数,或用%g自动省略末尾0 printf("%d%c %.1f", op1, op, op2); return 0; }
输入1 * 2时,会输出1* 2.0,如果要去掉.0,可以把%.1f换成%g,输出变为1* 2。
内容的提问来源于stack exchange,提问作者yyw
相关产品推荐
相关产品推荐

