我正在尝试创建一个可在Windows,Linux和osx之间移植的密码输入掩码功能。到目前为止,我的代码在linux和osx中完美运行,但是windows给了我一个问题。
有没有人知道为什么在Windows中fgetc要求我在退出while循环之前按两次enter
键?
static int get_password(char *password, int mask)
{
int max_pass_len = 512;
#ifdef _WIN32
HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
DWORD prev_mode = 0;
GetConsoleMode(hstdin, &mode);
GetConsoleMode(hstdin, &prev_mode);
SetConsoleMode(hstdin, mode & ~(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT));
#else
static struct termios prev_terminal;
static struct termios terminal;
tcgetattr(STDIN_FILENO, &prev_terminal);
memcpy (&terminal, &prev_terminal, sizeof(struct termios));
terminal.c_lflag &= ~(ICANON | ECHO);
terminal.c_cc[VTIME] = 0;
terminal.c_cc[VMIN] = 1;
tcsetattr(STDIN_FILENO, TCSANOW, &terminal);
#endif
size_t idx = 0; /* index, number of chars in read */
int c = 0;
const char BACKSPACE = 8;
const char RETURN = 13;
/* read chars from fp, mask if valid char specified */
while (((c = fgetc(stdin)) != '\n' && c != RETURN && c != EOF && idx < max_pass_len - 1) ||
(idx == max_pass_len - 1 && c == 127))
{
if (c != 127 && c != BACKSPACE) {
if (31 < mask && mask < 127) /* valid ascii char */
fputc(mask, stdout);
password[idx++] = c;
} else if (idx > 0) { /* handle backspace (del) */
if (31 < mask && mask < 127) {
fputc(0x8, stdout);
fputc(' ', stdout);
fputc(0x8, stdout);
}
password[--idx] = 0;
}
}
password[idx] = 0; /* null-terminate */
// go back to the previous settings
#ifdef _WIN32
SetConsoleMode(hstdin, prev_mode);
#else
tcsetattr(STDIN_FILENO, TCSANOW, &prev_terminal);
#endif
return idx; /* number of chars in passwd */
}
```
答案 0 :(得分:0)
使用ReadConsole解决问题
#ifdef _WIN32
long unsigned int char_read = 0;
while ((ReadConsole(hstdin, &c, 1, &char_read, NULL) && c != '\n' && c != RETURN && c != EOF && idx < max_pass_len - 1) ||
(idx == max_pass_len - 1 && c == BACKSPACE))
#else
while (((c = fgetc(stdin)) != '\n' && c != EOF && idx < max_pass_len - 1) ||
(idx == max_pass_len - 1 && c == 127))
#endif