C语言首个项目:fflush(stdin)未定义时如何正确清空输入缓冲区
可行解决方案
1. 实现跨平台标准输入缓冲区清理函数
直接使用C标准库函数实现,不依赖任何编译器扩展,逻辑是把输入缓冲区中直到换行符/EOF的所有剩余字符全部读完丢弃:
void clear_stdin_buffer() { int c; while ((c = getchar()) != '\n' && c != EOF); }
注意这里用int类型存储getchar的返回值,是为了兼容EOF(值为-1,不在char的取值范围内)
2. 清理逻辑插入位置
你需要在两个位置调用这个清理函数:
- 第一处:
scanf("%lf %c %lf", &a, &oper, &b);执行完成后,不管输入是否匹配成功,都要清理残留的输入内容,避免后续读取操作读到垃圾数据 - 第二处:如果你把非标准的
getch()替换为标准库的getchar(),需要在读取option之后再清理一次缓冲区,避免残留的回车影响下一轮循环
3. 修改后完整可运行代码
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> // 兼容system函数 // 输入缓冲区清理函数 void clear_stdin_buffer() { int c; while ((c = getchar()) != '\n' && c != EOF); } // 判断是否为整数 bool isInteger(double val) { int truncated = (int)val; return (val == truncated); } int main() { double result, a, b; char oper, option = 'y'; while(option == 'y') { system("cls"); printf("Enter number and operator to solve:\n\nExample [a + b][a - b][a * b][a / b]\n"); // 先判断scanf的返回值,避免输入不匹配时变量值为垃圾值 int read_cnt = scanf("%lf %c %lf", &a, &oper, &b); clear_stdin_buffer(); // 读完输入立刻清理缓冲区 if(read_cnt != 3) { printf("Input format error!\n"); } else if(isInteger(a) && isInteger(b)) { switch(oper) { case '+': result = a + b; printf("%.1lf %c %.1lf = %.1lf\n\n", a, oper, b, result); break; case '-': result = a - b; printf("%.1lf %c %.1lf = %.1lf\n\n", a, oper, b, result); break; case '*': result = a * b; printf("%.1lf %c %.1lf = %.1lf\n\n", a, oper, b, result); break; case '/': if(b == 0) { // 新增除零判断,避免非法运算 printf("Divide by zero error!\n"); } else { result = a / b; printf("%.1lf %c %.1lf = %.1lf\n\n", a, oper, b, result); } break; default: printf("Invalid Operator!\n"); } } else { printf("Input number is not integer!\n"); } printf("Do you want to retry y/n?"); option = getchar(); clear_stdin_buffer(); // 清理输入y/n之后残留的回车 } return 0; }
补充说明
- 原代码中的
getch()是Windows平台特有的非标准函数,替换为标准库的getchar()可实现跨平台使用 - 新增的
scanf返回值判断,可避免用户输入格式错误(比如输入字母代替数字)时程序逻辑异常 - 上述
clear_stdin_buffer完全遵循C标准,在所有符合标准的编译器上都可正常运行,不需要依赖fflush(stdin)这种未定义行为
内容的提问来源于stack exchange,提问作者kurtivan23
相关产品推荐
相关产品推荐

