Буферизация ввода и маскировка ввода пароля C ++

Я использую фрагмент кода из cplusplus и не могу понять, почему этот код просто пропускает часть ввода для пароля и просто переходит прямо к вводу для EMAIL.

//function to mask the input for password
    string getpass(const char *prompt, bool show_asterisk=true)
    {
      const char BACKSPACE=127;
      const char RETURN=10;

      string password;
      unsigned char ch=0;

      //cout <<prompt<<endl;

      while((ch=getch())!=RETURN)
        {
           if(ch==BACKSPACE)
             {
                if(password.length()!=0)
                  {
                     if(show_asterisk)
                     cout <<"\b \b";
                     password.resize(password.length()-1);
                  }
             }
           else
             {
                 password+=ch;
                 if(show_asterisk)
                     cout <<'*';
             }
        }
      cout <<endl;
      return password;
    }  

И вот я вызываю эту функцию:

void AgendaUI::userRegister(void)
  {
    string name, password, email, phone;
    //cout << "\n[register] [username] [password] [email] [phone]" << endl;
    cout << "\n[regist]";
    cout << "\n[username] ";
    cin >> name;
    cout << "[password] ";
    password = getpass("Enter the password",true);
    cout << "\n[email] ";
    cin >> email;
    cout << "[phone] ";
    cin >> phone;
}  

Терминал


person casper    schedule 30.11.2018    source источник


Ответы (1)


Потому что, когда ваш пользователь вводил имя пользователя, он также вводил символ Enter (именно так их терминал узнал, что нужно отправить строку). Этот символ не был прочитан cin >> name и все еще находится в буфере. Затем getpass считывает его как первый символ и немедленно останавливается.

Обратите внимание на то, что ваш код не совпадает с кодом статьи, который не запрашивает имя пользователя и показывает довольно хрупкий getpass (например, он ломается при простом добавлении базового кода, который вы добавили, и, похоже, полагается на < em> termios, которые вы незаметно удалили). В общем, старайтесь не изучать C ++ из статей на веб-сайтах. Изучите это из хорошей книги!

Вы можете исправить это, добавив cin.ignore(256, '\n') после cin >> name, хотя, честно говоря, это немного взломать, и, возможно, было бы лучше извлечь вместо имени пользователя используется std::getline.

person Lightness Races in Orbit    schedule 30.11.2018
comment
tl; dr вы не можете просто взять функцию из более крупной программы и поместить ее в другую программу, удаляя биты и добавляя другие биты, не понимая, что они делают, и ожидать, что это будет работать так же. - person Lightness Races in Orbit; 30.11.2018