我使用的是cplusplus的一段代码,我不明白为什么这段代码跳过了密码的输入部分,直接跳到了电子邮件的输入部分。
//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;
}
终端
因为当用户输入用户名时,他们也输入了Enter字符(这就是他们的终端如何提交行的(。cin >> name
未读取该字符,该字符仍在缓冲区中。然后,getpass
将其作为第一个字符读取,并立即停止。
请注意,您的代码与文章的代码不同,文章的代码不要求用户名,并且显示了一个相当脆弱的getpass
(例如,当简单地添加您添加的基本代码时,它会崩溃,并且似乎依赖于您悄悄删除的termios黑客(。一般来说,尽量不要从网站上的文章中学习C++。不如从一本好书中学习!
您可以通过在cin >> name
之后添加cin.ignore(256, 'n')
来解决此问题,尽管坦率地说,这有点像黑客攻击,可以说使用std::getline
提取用户名会更好。
我不明白为什么这段代码跳过了密码的输入部分
@Lightness在回答原因时提到了原因
要清除输入用户名后缓冲的换行符,需要清除输入流。
对于c,使用此fflush(stdin);
对于c++,请使用此std::cout.flush();
或者,你可以像我有时做的那样做另一件事,即在输入用户名后使用getchar();
。这种方法不是一种标准的方法,但它是有效的。有时我们需要与getchar();
一起冲洗流
根据您的代码示例,我认为您试图屏蔽用户输入的密码
为此,您可以在键入时禁用字符的回显。
当然,它不会打印任何花哨的星号或任何其他符号,相反,由于用户不断键入密码,输入字段将为空。
下面给出了我在这里使用的Windows&nix系统:
//Include other headers as well as per your program need
#ifdef WIN32
#include <windows.h>
#else
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#endif
void stdecho(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
}
代码用法如下:
cout<<"nLogin to begin :)";
cout<<"ntUsername : ";
cin>>username;
getchar(); // Here I am using `getchar();` to clear the new line remains in the input buffer
//you can also flush the input stream instead if this does not work or you can combine both
cout<<"tPassword : ";
stdecho(false); //From now on I am disabling the echo from `std::cin`
getline(cin, password); //No character will show up as you type your password
stdecho(true); //From here the `std::cin` echo will be enabled again i.e., characters will start showing up again
pashash = hash(password); //Ignore from here...
password.erase();
有关更多详细信息和答案,请参阅"从std::cin读取密码"。
这个过程在控制台中的屏幕截图:图片01&图像02