You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 22:15:29