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

如何在读取标准输入时避免显示^C/^D?仅允许使用tcsetattr与tcgetattr

如何用tcsetattr/tcgetattr实现Ctrl+C/Ctrl+D不显示C/D

要实现按下Ctrl+C、Ctrl+D时不显示对应的C、D符号,核心是修改终端的本地模式(local modes),关闭ECHOCTL标志——这个标志负责回显控制字符(比如C、D这类)。

以下是完整实现代码:

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>

struct termios orig_termios;

// 程序退出前恢复终端原始属性
void restore_terminal() {
    tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
}

int main() {
    struct termios term;

    // 获取当前终端属性
    if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) {
        perror("tcgetattr failed");
        return 1;
    }
    // 注册退出时的恢复函数,避免终端状态异常
    atexit(restore_terminal);

    // 复制属性进行修改,不直接改动原始配置
    term = orig_termios;
    // 关闭ECHOCTL标志,禁止回显控制字符
    term.c_lflag &= ~ECHOCTL;

    // 立即应用修改后的终端属性
    if (tcsetattr(STDIN_FILENO, TCSANOW, &term) == -1) {
        perror("tcsetattr failed");
        return 1;
    }

    // 测试逻辑:读取输入直到用户输入q退出
    char c;
    printf("按下Ctrl+C/Ctrl+D不会显示^C/^D,输入q退出\n");
    while (read(STDIN_FILENO, &c, 1) == 1) {
        if (c == 'q') {
            break;
        }
        putchar(c); // 普通输入字符正常回显
    }

    return 0;
}

关键细节说明:

  • tcgetattr:读取当前终端的属性配置,保存到orig_termios是为了程序退出时恢复终端原始状态
  • ECHOCTL:终端本地模式的标志位,开启时会将控制字符(如Ctrl+C对应ASCII 3)显示为^C,关闭后就不会产生这类回显
  • tcsetattr的TCSANOW参数:让修改的属性立即生效,无需等待输入缓冲区处理完成
  • atexit注册恢复函数:确保无论程序正常退出还是异常终止(除了强制kill),终端都能回到初始状态,避免后续终端操作出现异常

编译运行后,按下Ctrl+C、Ctrl+D就不会再看到C、D的回显,普通输入字符的显示不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:40:42