使用scanf即便限制输入长度、调用fflush仍出现输入溢出问题
问题解答
1. 输入超长后第二个scanf不触发的原因
scanf("%8ld", &bank_account)的执行逻辑是最多从输入缓冲区读取8个数字字符转换为long类型存入变量,你输入的123123123123共12位,读完前8位后,剩余的3123会残留在输入缓冲区中,不会自动清除。- 你代码里的
fflush(stdin)属于无效操作,不会清除缓冲区残留的内容,第二个scanf("%lf", &money)执行时会直接读取残留的3123转换为double类型存入money,自然不会等待你手动输入。
2. fflush(stdin)为什么是错误写法
C语言标准明确规定,fflush仅对输出流或者最近执行过输出操作的更新流有定义,针对输入流stdin调用fflush的行为是未定义的:
- 只有部分老旧的微软编译器(如VC6)自己做了私有扩展,支持用
fflush(stdin)清空输入缓冲区 - 主流的GCC、Clang等编译器都不支持这个用法,调用后不会产生任何清空缓冲区的效果
3. 为什么教材会出现这类错误写法
很多C语言教材成书时间较早,或者面向特定编译器环境编写,会把厂商私有扩展、当时民间约定俗成的错误写法当成标准用法收录,没有考虑跨平台、跨标准的兼容性,这类遗留问题在很多老旧教材里都普遍存在。
4. 关于你提到的“溢出”误解
你当前的场景没有发生栈溢出:
long类型至少可以存储32位整数,8位十进制数最大为99999999,远小于32位整数的最大值2^31-1,完全可以正常存入bank_account,不存在变量溢出的问题- 你遇到的是输入缓冲区残留导致的读取逻辑问题,和局部变量栈分配没有关系
修复方案
把代码里的fflush(stdin)替换为以下代码,即可手动清空输入缓冲区的残留内容,让第二个scanf正常等待输入:
int c; while ((c = getchar()) != '\n' && c != EOF);
另外注意你的printf有格式符错误:bank_account是long类型,输出应该用%ld而不是%d,否则在int和long长度不同的平台上会出现输出异常。
内容的提问来源于stack exchange,提问作者jupiter_jazz
相关产品推荐
相关产品推荐

