C语言程序异常:执行功能后startProgram被连续调用两次
问题:计算阶乘/数字和后程序重复弹出菜单
我写了一个程序,让用户选择计算数字阶乘或数字之和,按下'N'可退出,否则循环运行。功能已经实现,但每次完成计算后,startProgram函数会被连续调用两次,导致菜单重复显示,不符合预期。
我的代码
#include <stdio.h> #include <stdlib.h> void getFactorial(void); void getSumOfDigits(void); void startProgram(); int main() { startProgram(); return 0; } void startProgram() { char operation = ' '; printf( "Select operation: \n" "\t1 For Factorial of a number\n" "\t2 For Sum of digits in a number\n\n" "\tPress N' to exit program\n\n" "\t" ); operation = getchar(); if(operation == 49) getFactorial(); else if(operation == 50) getSumOfDigits(); else if(operation == 78 || operation == 110) exit(0); startProgram(); } void getFactorial() { int facto = 1, n1 = 0; printf("\n\tEnter the number you want to get factorial of: "); scanf("%d", &n1); for(int i = 1; i <= n1; i++) { facto*=i; } printf("\n\tFactorial: %d\n\n\t", facto); } void getSumOfDigits() { int lastDigit = 0, digit = 0, sum = 0; printf("\n\tEnter a digit: "); scanf("%d", &digit); while(digit) { lastDigit = digit % 10; sum += lastDigit; digit /= 10; } printf("\n\tSum: %d\n\n\t", sum); }
问题现象
计算阶乘后的输出示例:
Select operation: 1 For Factorial of a number 2 For Sum of digits in a number Press N' to exit program 1 Enter the number you want to get factorial of: 5 Factorial: 120 Select operation: 1 For Factorial of a number 2 For Sum of digits in a number Press N' to exit program Select operation: 1 For Factorial of a number 2 For Sum of digits in a number Press N' to exit program
问题原因
本质是输入缓冲区残留的换行符在搞鬼:当你用scanf("%d")读取数字时,用户输入数字后按下的回车键(\n)不会被scanf读取,会留在输入缓冲区里。等计算完成后回到startProgram,getchar()会直接读取这个残留的\n,而\n不匹配任何操作选项,程序会再次调用startProgram,于是菜单就显示了两次。
解决方案
方法1:彻底清空输入缓冲区(推荐)
在getFactorial和getSumOfDigits的scanf之后,添加循环清空缓冲区里的所有残留字符:
修改后的getFactorial函数:
void getFactorial() { int facto = 1, n1 = 0; printf("\n\tEnter the number you want to get factorial of: "); scanf("%d", &n1); // 清空输入缓冲区,直到读取到换行符 while(getchar() != '\n'); for(int i = 1; i <= n1; i++) { facto *= i; } printf("\n\tFactorial: %d\n\n\t", facto); }
修改后的getSumOfDigits函数:
void getSumOfDigits() { int lastDigit = 0, digit = 0, sum = 0; printf("\n\tEnter a digit: "); scanf("%d", &digit); // 清空输入缓冲区,直到读取到换行符 while(getchar() != '\n'); while(digit) { lastDigit = digit % 10; sum += lastDigit; digit /= 10; } printf("\n\tSum: %d\n\n\t", sum); }
方法2:用scanf直接丢弃换行符
在scanf的格式字符串末尾加上%*c,让scanf自动读取并丢弃紧跟数字后的第一个字符(也就是换行符):
scanf("%d%*c", &n1); // 用于getFactorial scanf("%d%*c", &digit); // 用于getSumOfDigits
这种方法更简洁,但如果用户输入数字后还输入了其他字符(比如5abc),只会丢弃第一个额外字符,不如方法1彻底。
额外小修复
菜单里的Press N' to exit program多了一个单引号,改成Press 'N' to exit program更规范。
内容的提问来源于stack exchange,提问作者vatsal chauhan
相关产品推荐
相关产品推荐

