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

如何在用户输入时终止scanf?1秒超时终止scanf问题求助

问题分析

原代码的核心问题是scanf("%d", &num)属于阻塞式输入,一旦调用就会强制等待用户输入完整数字并按下回车,哪怕超时时间已到也无法终止。只有用户完全没按键时,超时循环才能正常结束。此外还有两处冗余问题:

  • fgetc(stdin)和scanf("%c", &ch)重复读取输入缓冲区,导致需要额外按下回车才能继续流程
  • if (ch == 0x0A || ch != 0x0A)逻辑无意义,该条件永远成立
解决方案

改用逐字符非阻塞读取结合计时逻辑:用户按下回车启动计时后,逐字符捕获输入,每读取一个字符就检查是否超时;同时收集有效数字字符,超时后再将收集到的字符转换为整数。

修改后的Windows平台代码:

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>

int main() {
    int i = 0;
    int max = 0;
    int num;
    int counter = 0;

    while (i != 10) {
        printf("Hit enter when ready\n");
        // 清空输入缓冲区,避免残留字符干扰
        while (getchar() != '\n'); 

        DWORD start_time = GetTickCount();
        DWORD check_time = start_time + 1000;
        printf("ENTER KEY is pressed. You have 1 second to enter a number:\n");

        char input_buf[20] = {0};
        int buf_idx = 0;
        num = -1;

        while (GetTickCount() < check_time) {
            if (_kbhit()) {
                char ch = _getch();
                // 支持退格键删除输入
                if (ch == '\b' && buf_idx > 0) {
                    buf_idx--;
                    input_buf[buf_idx] = '\0';
                    printf("\b \b"); // 控制台回显删除效果
                    continue;
                }
                // 按下回车则提前结束输入
                if (ch == '\n') {
                    break;
                }
                // 仅接受数字字符
                if (ch >= '0' && ch <= '9') {
                    input_buf[buf_idx++] = ch;
                    printf("%c", ch); // 实时回显输入内容
                }
            }
            Sleep(10); // 降低循环CPU占用率
        }

        // 将收集到的字符转换为整数
        if (buf_idx > 0) {
            num = atoi(input_buf);
            printf("\nYou entered: %d\n", num);
            counter++;
            if (num > max) {
                max = num;
            }
        } else {
            printf("\nTimeout :( No number entered.\n");
        }

        i++;
    }

    printf("\nYou entered %d numbers\n", counter);
    printf("The biggest number is %d\n", max);
    return 0;
}
关键改进点
  • 用while (getchar() != '\n')清空输入缓冲区,彻底解决残留字符导致的额外等待问题
  • 用_kbhit()检测按键、_getch()非阻塞读取单个字符,替代阻塞式的scanf,让超时逻辑能实时生效
  • 支持退格键修正输入,提升交互体验
  • 加入Sleep(10)降低循环对CPU的占用
  • 移除冗余的无意义条件判断

内容的提问来源于stack exchange,提问作者Chihab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:50:24