CCS 102(C语言编程):如何在循环中/每次循环后重新初始化变量
问题根因与修复方案
你遇到的问题由两个常见的C语言输入逻辑漏洞导致:
- 变量
a、b、operation定义在循环外部,栈上的局部变量只会初始化一次,每次循环如果没有主动重置,上轮输入的合法值会在本轮输入异常时被复用,导致错误执行计算逻辑 - 没有判断
scanf的返回值,也没有处理输入匹配失败后的残留缓冲区数据,异常输入后后续的读取操作会直接拿到缓冲区的垃圾内容,甚至跳过用户交互步骤
修复步骤
- 将变量声明挪到循环内部,每次循环执行时自动重新初始化变量,彻底避免上轮循环的值残留影响本轮逻辑
- 校验
scanf返回值,scanf会返回成功匹配的参数个数,你当前的输入格式需要匹配3个参数,只要返回值不等于3就判定为输入格式错误 - 输入异常时清空缓冲区,匹配失败后把输入缓冲区里的所有残留字符全部读完丢弃,避免影响后续的输入读取
- 读取重试选项前清空缓冲区残留的换行符,防止
getch直接读到缓冲区残留的控制字符,跳过用户输入环节
修改后的完整代码
#include <stdio.h> #include <stdbool.h> #include <math.h> bool isInteger(double val) { int truncated = (int)val; return (val == truncated); } int main(int argc, char *argv[]) { char option = 'y'; while(option == 'y' || option == 'Y') { // 变量挪到循环内部,每次循环重新初始化 double a = NAN, b = NAN; char operation = 0; // system("cls"); printf("Enter number and operator to solve:\n\nExample [a + b][a - b][a * b][a / b]\n"); // 判断scanf返回值,必须成功匹配3个参数才算合法输入 int matchCnt = scanf("%lf %c %lf", &a, &operation, &b); if (matchCnt != 3) { printf("Input format error!\n"); // 清空输入缓冲区所有残留字符 while(getchar() != '\n'); } else if(isInteger(a) && isInteger(b)) { if(operation == '+') { printf("Result: %.1lf\n\n", a + b); } else if(operation == '-') { printf("Result: %.1lf\n\n", a - b); } else if(operation == '*') { printf("Result: %.1lf\n\n", a * b); } else if(operation == '/') { printf("Result: %.1lf\n\n", a / b); } else { printf("Invalid Operator!\n"); } // 合法输入也要清空缓冲区残留的换行 while(getchar() != '\n'); } else { printf("Input is not a digit!\n"); // 清空输入缓冲区 while(getchar() != '\n'); } printf("Do you want to retry [y]/[n]?"); option = getch(); printf("\n"); } return 0; }
内容的提问来源于stack exchange,提问作者kurtivan23
相关产品推荐
相关产品推荐

