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

Debian Linux下如何实现C语言计数程序按Q键退出?

解决Debian Linux下C语言计数程序按Q退出的问题

问题根源

你之前的实现存在三个核心问题:

  1. getchar()放在循环结束后执行,无法在计数过程中响应按键
  2. 终端默认是行缓冲模式,getchar()必须等按下回车才会返回,且是阻塞状态,会打断定时逻辑
  3. 判断条件错误:'Q'的ASCII值是81(小写q是113),不是1

解决方案

在Linux下需要修改终端输入模式,关闭行缓冲和回显,用非阻塞方式检测按键。具体步骤:

  • 保存终端原有属性,程序退出前恢复(避免终端状态异常)
  • 将终端设置为非规范模式,让输入字符立即被读取,不需要回车
  • 设置标准输入为非阻塞模式,避免读取操作阻塞定时逻辑
  • 在计数循环中检测按键,若为'Q'或'q'则退出循环

修改后的完整代码

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>  // 终端控制头文件
#include <fcntl.h>    // 文件控制头文件

int main() {
    struct timespec duration;
    struct timespec remaining; 
    int time, num;  
    struct termios old_term, new_term;
    int fd = STDIN_FILENO;

    // 保存原有终端属性
    tcgetattr(fd, &old_term);
    // 复制属性并修改为非规范模式
    new_term = old_term;
    new_term.c_lflag &= ~(ICANON | ECHO);  // 关闭行缓冲和回显
    new_term.c_cc[VMIN] = 0;               // 最少读取0个字符(非阻塞)
    new_term.c_cc[VTIME] = 0;              // 超时时间0
    tcsetattr(fd, TCSANOW, &new_term);

    // 设置标准输入为非阻塞模式
    int flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);

    duration.tv_sec = 1;    
    duration.tv_nsec = 0;   

    time = 0;
    num = 0;
    
    while(time <= 32767)
    {
      int result = nanosleep(&duration, &remaining);
      num++;
      if (result == 0) 
      {
          printf("Seconds Passed: %d\n", num);
          time++;
      }
      else if (result == -1)
      {
         printf("Error with nanosleep\n");
         break;  // 替换goto,更规范
      }

      // 检测按键输入
      char c;
      ssize_t read_len = read(fd, &c, 1);
      if (read_len > 0 && (c == 'Q' || c == 'q')) {
          printf("\n退出程序\n");
          break;
      }
    }

    // 恢复终端原有属性
    tcsetattr(fd, TCSANOW, &old_term);
    fcntl(fd, F_SETFL, flags);  // 恢复文件状态标志

    return 0;
}

关键代码解释

  • tcgetattr/tcsetattr:用于获取和设置终端属性,关闭ICANON(行缓冲)和ECHO(回显)
  • fcntl:设置标准输入为非阻塞模式,read()不会等待输入,没有字符时直接返回-1
  • 循环内的read():每次定时结束后检测是否有按键,若读取到'Q'或'q'则退出循环
  • 程序结束前必须恢复终端属性,否则终端会保持无回显、无行缓冲的异常状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:56:08