如何在用户输入时终止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
相关产品推荐
相关产品推荐

