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

C 語言跨平台密碼輸入顯示星號完整實作(Windows/Linux)

     編輯:關於C語言

核心問題

標準 getchar() 會回顯字元,需使用無回顯、無緩衝的單字元讀取函數。Windows 提供 conio.h 的 getch(),Linux 需自行實作或使用 termios 控制終端機屬性。

進階版密碼輸入函數特性

  • 顯示 * 遮蔽字元
  • 支援 Backspace 刪除(含視覺回饋)
  • 長度限制與超長警示(ALARM 鈴聲)
  • 處理 EOF(Ctrl+D/Ctrl+Z)清除緩衝並回傳 NULL
  • 使用 static 緩衝區回傳,呼叫端需自行 strcpy 保存

跨平台 getch() 實作

#ifndef _WIN32
#include <termio.h>
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
int getch(void) {
    struct termios tm, tm_old;
    int fd = STDIN_FILENO, c;
    if (tcgetattr(fd, &tm) < 0) return -1;
    tm_old = tm;
    cfmakeraw(&tm);          // 關閉標準輸入緩衝與回顯
    if (tcsetattr(fd, TCSANOW, &tm) < 0) return -1;
    c = fgetc(stdin);
    tcsetattr(fd, TCSANOW, &tm_old); // 還原終端機屬性
    return c;
}
#else
#include <conio.h>
#endif

完整 getPasswd() 函數

#define MAX_LEN 8
#define BACKSPACE 8
#define ENTER 13
#define ALARM 7

char *getPasswd(const char *prompt) {
    int i = 0, ch;
    static char p[MAX_LEN + 1] = "";
    printf("%s", prompt);
    while ((ch = getch()) != -1 && ch != ENTER) {
        if (i == MAX_LEN && ch != BACKSPACE) { putchar(ALARM); continue; }
        if (ch == BACKSPACE) {
            if (i == 0) { putchar(ALARM); continue; }
            i--; putchar(BACKSPACE); putchar(' '); putchar(BACKSPACE);
        } else {
            p[i++] = ch; putchar('*');
        }
    }
    if (ch == -1) { while (i--) p[i] = '\0'; return NULL; }
    p[i] = '\0'; printf("\n"); return p;
}

安全性補充

  • UNIX 系統建議直接使用 getpass()(雖標示棄用但廣泛支援)。
  • 密碼驗證前請以 crypt() 或現代雜湊函式(bcrypt, Argon2)加密儲存。
  • 使用後立即清除靜態緩衝區(memset(p, 0, sizeof(p)))。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved