如何实现ESC键终止程序并处理整数输入的C语言阶乘程序
阶乘程序的输入处理与ESC终止解决方案
问题1:非法输入导致无限循环的修复
当scanf("%d", &num)读取非整数输入时,无效字符会留在输入缓冲区中,下一次循环scanf会重复读取这些无效内容,导致持续返回失败,陷入无限循环。
修复步骤:
- 当
scanf返回值不等于1时,清空输入缓冲区里的所有残留字符,直到遇到换行符或EOF - 统一变量名(你代码里混用了
sayi和num,需保持一致)
问题2:添加ESC键终止程序的实现
默认scanf无法直接检测ESC这类单字符按键,需要直接读取键盘输入。不同平台实现略有差异:
- Windows平台可使用
<conio.h>的_getch()函数(无需回车即可读取按键) - Linux/macOS需通过
<termios.h>配置终端为无缓冲模式,再读取按键
Windows版本完整代码
#include <stdio.h> #include <conio.h> int main() { int num, factorial; int input_result; char ch; while (1) { // 实时检测ESC按键 if (_kbhit()) { ch = _getch(); if (ch == 27) { // ESC键的ASCII码为27 printf("\n程序已终止\n"); break; } } factorial = 1; printf("Enter Number : "); input_result = scanf("%d", &num); // 处理非法输入 if (input_result != 1) { printf("Error Occured.\n"); // 清空输入缓冲区 while ((getchar()) != '\n'); continue; } // 计算阶乘(注意:int类型仅能正确计算到12!,更大数值会溢出) for (int i = 1; i <= num; i++) { factorial *= i; } printf("Factorial : %d\n", factorial); } return 0; }
Linux/macOS版本完整代码
#include <stdio.h> #include <termios.h> #include <unistd.h> #include <sys/select.h> // 实现无缓冲读取单个按键 int getch() { struct termios oldt, newt; int ch; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); return ch; } int main() { int num, factorial; int input_result; char ch; while (1) { // 非阻塞检测按键输入 fd_set readfds; struct timeval tv = {0, 0}; FD_ZERO(&readfds); FD_SET(STDIN_FILENO, &readfds); if (select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv) > 0) { ch = getch(); if (ch == 27) { printf("\n程序已终止\n"); break; } // 非ESC按键放回输入缓冲区,不影响后续scanf读取 ungetc(ch, stdin); } factorial = 1; printf("Enter Number : "); input_result = scanf("%d", &num); if (input_result != 1) { printf("Error Occured.\n"); while ((getchar()) != '\n'); continue; } for (int i = 1; i <= num; i++) { factorial *= i; } printf("Factorial : %d\n", factorial); } return 0; }
额外提示
- 如果需要计算更大数值的阶乘,可将
factorial和循环变量改为long long类型,扩大数值范围 - 输入负数时阶乘逻辑不符合数学定义,可额外添加负数输入的判断逻辑
内容的提问来源于stack exchange,提问作者DarkPirat3
相关产品推荐
相关产品推荐

