c语言 - fgetc 需要在 WINDOWS 上按两次'enter'键



我正在尝试在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    */
}

````

使用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

最新更新