互動式遊戲、密碼輸入、即時按鍵偵測需逐字元讀取,不等待 Enter,且不回顯字元。
#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 控制台 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); // 恢復
SIGKILL)無法執行 atexit 恢復,終端機可能保持原始模式,需手動 reset 指令恢復。main 開頭設置 signal(SIGINT, handler) 捕獲 Ctrl+C 並恢復終端機。tcsetattr 的 TCSANOW 立即生效,TCSADRAIN 等輸出耗盡,TCSAFLUSH 清空輸入緩衝。終端機屬性控制是編寫高互動性控制台程式的核心技能,掌握 termios 結構與旗標組合,即可實現類 getch()、密碼輸入、即時遊戲循環等功能。