为什么C语言代码中只有第一个scanf()正常其余被跳过执行?
问题原因分析
scanf格式符使用非法:%.2f是仅适用于printf的精度控制语法,scanf的格式规范中不存在该写法,属于未定义行为。不同编译器的C标准库对该非法写法的处理逻辑不同:部分库做了兼容处理,因此相同代码在其他设备可以正常运行;你本地的C库不兼容该写法,会直接触发scanf读取失败。- 输入缓冲区残留导致后续读取跳过:
scanf读取失败后,你输入的内容(包括输入结束的换行符)不会被清空,会一直残留在输入缓冲区中。后续的scanf读取时会首先匹配缓冲区的残留内容,和格式要求不匹配就会直接返回失败,表现为代码直接跳过输入步骤继续执行。 - 额外未定义行为:
principal变量声明时未初始化,首次进入while循环就判断principal == -1,此时变量值是内存中的随机垃圾值,可能触发意料之外的逻辑。
修复方案
将scanf的%.2f格式符替换为合法的%f即可,若需要限制数值保留两位小数,可在输出或后续计算环节处理,不要在输入读取阶段添加精度限制。建议额外添加scanf返回值校验,以及输入缓冲区清空逻辑,避免非法输入导致后续读取全部失败。修复后的参考代码如下:
#include <stdio.h> #include <stdbool.h> int main() { float interest, principal = 0, rate; int days; while(true) { printf("Enter loan principal (Enter -1 to end): \n"); // 校验scanf返回值,读取失败或输入为-1时直接退出 if(scanf("%f", &principal) != 1 || principal == -1) { break; } printf("Enter interest rate: \n"); scanf("%f", &rate); printf("Enter term of the loan in days: \n"); scanf("%d", &days); // 清空当前行剩余的残留内容,避免非法输入干扰后续读取 while(getchar() != '\n'); } return 0; }
内容的提问来源于stack exchange,提问作者Muhammad Koziev
相关产品推荐
相关产品推荐

