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

C语言简易计时器问题:getchar未等待按键即启动计时

C语言计时器中getchar()不等待按键的问题解决

问题重现

你编写的C语言计时器代码如下:

#include <stdio.h>
#include <time.h>

int main()
{
    char c;
    time_t start, end;
    long int day, day_start, day_end, hr, hr_start, hr_end, min, min_start, min_end, sec, sec_start, sec_end, time_diff;
    
    printf ("Enter time in hours, minutes and seconds for which the timer is to be set\n");
    scanf (" %ld %ld %ld %ld", &day, &hr, &min, &sec);
    
    
    printf("Press any key to start timer\n");
    fflush (stdin);
    getchar ();
    
    time (&start);
    start = start + 19800; // 19800 is added to compensate for the time difference between GMT and Indian std time.
    sec_start = start % 86400;
    min_start = sec_start / 60;
    sec_start = sec_start % 60;
    hr_start  = min_start / 60;
    min_start = min_start % 60;
    day_start = hr_start / 24;
    hr_start  = hr_start % 24;
    
    printf("Timer started : %2ld : %2ld : %2ld\n", hr_start, min_start, sec_start);
    
    time_diff = day * 86400 + hr * 3600 + min * 60 + sec;
    
    while (1)
    {
        time (&end);
        end = end + 19800;
        
        if (start + time_diff <= end)
        break;
    }
    
    
    sec_end = end % 86400;
    min_end = sec_end / 60;
    sec_end = sec_end % 60;
    hr_end  = min_end / 60;
    min_end = min_end % 60;
    day_end = hr_end / 24;
    hr_end  = hr_end % 24;
    
    printf("Timer ended   : %2ld : %2ld : %2ld\n", hr_end, min_end, sec_end);
    
    return 0;
}

程序运行时,getchar()并未等待按键就直接启动计时器。

错误原因

  1. 输入缓冲区残留换行符:当你用scanf输入完时间参数并按下回车后,回车对应的换行符\n会留在标准输入缓冲区中。
  2. fflush(stdin)无效:C语言标准中,fflush仅对输出流有定义,用于输入流时属于未定义行为,不同编译器可能有不同表现,无法可靠清空输入缓冲区。
  3. getchar()读取残留字符:此时调用getchar(),它会直接读取缓冲区中残留的换行符,而非等待用户新的按键输入。

修复方案

替换fflush(stdin),用循环读取的方式清空输入缓冲区,确保getchar()能等待用户按键:

修改后的关键代码片段:

printf("Press any key to start timer\n");

// 清空scanf残留的输入缓冲区
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);

// 等待用户按键
getchar();

额外优化建议

  • 不要硬编码时区偏移(19800秒),可以使用localtime()函数直接获取本地时间,代码更通用且可靠:
    time(&start);
    struct tm *local_start = localtime(&start);
    // 直接使用local_start中的tm_hour、tm_min、tm_sec等字段
    
  • 循环等待计时器结束时,建议加入sleep(1),避免CPU空转:
    while (1)
    {
        time (&end);
        if (difftime(end, start) >= time_diff)
            break;
        sleep(1); // 每秒检查一次,降低CPU占用
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:25:56