web-dev-qa-db-fra.com

Lire un mot de passe depuis std :: cin

J'ai besoin de lire un mot de passe à partir de l'entrée standard et je voulais std::cin ne pas faire écho aux caractères saisis par l'utilisateur ...

Comment puis-je désactiver l'écho de std :: cin?

voici le code que j'utilise actuellement:

string passwd;
cout << "Enter the password: ";
getline( cin, passwd );

Je cherche un moyen agnostique pour le système d'exploitation de le faire. Ici il existe des moyens de le faire dans Windows et * nix.

52
Vargas

La réponse @ wrang-wrang était vraiment bonne, mais ne répondait pas à mes besoins, voici à quoi ressemble mon code final (qui était basé sur this ):

#ifdef WIN32
#include <windows.h>
#else
#include <termios.h>
#include <unistd.h>
#endif

void SetStdinEcho(bool enable = true)
{
#ifdef WIN32
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 
    DWORD mode;
    GetConsoleMode(hStdin, &mode);

    if( !enable )
        mode &= ~ENABLE_ECHO_INPUT;
    else
        mode |= ENABLE_ECHO_INPUT;

    SetConsoleMode(hStdin, mode );

#else
    struct termios tty;
    tcgetattr(STDIN_FILENO, &tty);
    if( !enable )
        tty.c_lflag &= ~ECHO;
    else
        tty.c_lflag |= ECHO;

    (void) tcsetattr(STDIN_FILENO, TCSANOW, &tty);
#endif
}

Exemple d'utilisation:

#include <iostream>
#include <string>

int main()
{
    SetStdinEcho(false);

    std::string password;
    std::cin >> password;

    SetStdinEcho(true);

    std::cout << password << std::endl;

    return 0;
}
63
Vargas

Il n'y a rien dans la norme pour cela.

Sous Unix, vous pouvez écrire des octets magiques selon le type de terminal.

Utilisez getpasswd s'il est disponible.

Vous pouvez system () /usr/bin/stty -echo pour désactiver l'écho, et /usr/bin/stty echo pour l'activer (encore une fois, sous unix).

Ce gars explique comment le faire sans utiliser "stty"; Je ne l'ai pas essayé moi-même.

11
Jonathan Graehl

Si vous ne vous souciez pas de la portabilité, vous pouvez utiliser _getch() dans VC.

#include <iostream>
#include <string>
#include <conio.h>

int main()
{
    std::string password;
    char ch;
    const char ENTER = 13;

    std::cout << "enter the password: ";

    while((ch = _getch()) != ENTER)
    {
        password += ch;
        std::cout << '*';
    }
}

Il existe également getwch() pour wide characters. Mon conseil est d'utiliser NCurse qui est également disponible dans les systèmes *nix.

7
AraK

Seule idée de ce que j'ai, vous pouvez lire le mot de passe char par char, et après cela, simplement imprimer le retour arrière ("\ b") et peut-être '*'.

3
IProblemFactory