首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言終端機原始模式控制:關閉標準輸入緩衝與回顯

     編輯:關於C語言

應用場景

互動式遊戲、密碼輸入、即時按鍵偵測需逐字元讀取,不等待 Enter,且不回顯字元。

核心 API (POSIX termios)

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

static struct termios oldt;

void disable_terminal_settings(void) {
    struct termios newt;
    tcgetattr(STDIN_FILENO, &oldt);   // 保存原屬性
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO); // 關閉規範模式(緩衝)與回顯
    tcsetattr(STDIN_FILENO, TCSANOW, &newt); // 立即生效
    // atexit(restore_terminal_settings); // 程式結束自動恢復
}

void restore_terminal_settings(void) {
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
}

void enable_terminal_settings(void) { // 手動恢復
    struct termios newt;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag |= (ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
}

關鍵旗標

  • ICANON:規範模式,開啟時按行緩衝(支援編輯、EOF 處理),關閉時逐字元即時讀取。
  • ECHO:回顯輸入字元,關閉用於密碼輸入。
  • ISIG:啟用信號字元 (Ctrl+C, Ctrl+Z 等),若需自行處理可關閉。
  • VMIN/VTIME (非規範模式下):控制 read() 最少字元數與超時。

完整範例:密碼輸入不回顯

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

int main() {
    disable_terminal_settings();
    char pwd[64] = {0};
    printf("Password: "); fflush(stdout);
    read(STDIN_FILENO, pwd, sizeof(pwd)-1);
    restore_terminal_settings();
    printf("\nInput: %s\n", pwd);
    return 0;
}

Windows 替代方案

// Windows 控制台 API
#include <windows.h>
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
SetConsoleMode(hStdin, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT));
// ... 讀取 ...
SetConsoleMode(hStdin, mode); // 恢復

注意事項

  • 程式異常退出(Crash、SIGKILL)無法執行 atexit 恢復,終端機可能保持原始模式,需手動 reset 指令恢復。
  • 建議在 main 開頭設置 signal(SIGINT, handler) 捕獲 Ctrl+C 並恢復終端機。
  • tcsetattr 的 TCSANOW 立即生效,TCSADRAIN 等輸出耗盡,TCSAFLUSH 清空輸入緩衝。

終端機屬性控制是編寫高互動性控制台程式的核心技能,掌握 termios 結構與旗標組合,即可實現類 getch()、密碼輸入、即時遊戲循環等功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved