標準 getchar() 會回顯字元,需使用無回顯、無緩衝的單字元讀取函數。Windows 提供 conio.h 的 getch(),Linux 需自行實作或使用 termios 控制終端機屬性。
* 遮蔽字元Backspace 刪除(含視覺回饋)ALARM 鈴聲)EOF(Ctrl+D/Ctrl+Z)清除緩衝並回傳 NULLstatic 緩衝區回傳,呼叫端需自行 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;
}
getpass()(雖標示棄用但廣泛支援)。crypt() 或現代雜湊函式(bcrypt, Argon2)加密儲存。memset(p, 0, sizeof(p)))。