如何在终端处于 RAW 模式下多次尝试输入密码?
我正在用 C++ 创建一个登录菜单,
我希望在程序终止之前让用户尝试输入密码 3 次。
如果用户第一次获得正确的密码,我的代码就可以正常运行。然后它会进入主菜单等。但是,如果用户输入的密码错误。终端将运行到:
Login: Fred
Password: ***
Wrong password
Please re-enter password:
之后,无论用户输入什么内容,都不会显示任何内容。甚至 ctrl-C 也无法退出程序。我想知道是否有人知道发生了什么事并且可以为我指出正确的方向。
以下是名为“HomePage”的类中“登录”方法的部分代码:
cout<<"Password: ";
while (loginAttempt < 3){ //The user gets to attempt to type
//the password 3 times
password = receivePassword(); //Receives password from user
if (flatMemberList[match].getPassword()==password){ //Check if the password is correct
cout<<endl<<"Welcome back "<<loginName<< endl; //If correct, display welcome message
return;
}
else{
loginAttempt++; //Record down one failed attempt
cout<<endl<<"Wrong password"<<endl; //If incorrect, display error
cout<<"Please re-enter password: ";
}
}
cout<<"you have exceeded the legal login attempts"<<endl;
exit(1);
其中 receivePassword() 是一个自定义方法,如下所示:
//This method is called when the user types in a password
//The terminal's setting is first changed to 'raw' configuration
//The password are taken in one letter at a time
//It outputs to terminal "*" instead of echoing the input
string HomePage::receivePassword(){
termios oldt, newt; //The structs for manipulation
char password[PaswordLength]; //Password held here
int j = 0; //Password index
tcgetattr(STDIN_FILENO, &oldt); //Get configuration details
newt = oldt;
cfmakeraw(&newt); //Set up new 'raw' configuration structure
//Set up new terminal configuration
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
cin.ignore(1000, '\n'); //flush all the buffers
while(true){
password[j] = cin.get();
if( password[j] == '\r' ) { //check if 'enter' key is entered
password[j] = '\0'; //replace cr with null to make C string
break;
}
cout.put('*'); //echo the asterisk
j++;
} ;
//Reset terminal to old configuration
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return password;
}
提前致谢
如果您认为问题可能在其他地方,请告诉我,我将发布代码。
I am creating a login menu in C++
i wish to give the user 3 attempts at entering the password before the program terminates.
My code runs fine if the user gets the password right the first time. It would then go into the home menu ect. However, if the user gets the password wrong. The terminal would run up to:
Login: Fred
Password: ***
Wrong password
Please re-enter password:
After which point nothing would show up regardless of what the user types. Not even ctrl-C can exit the program. I was wondering if anyone know what's going on and can point me in the right direction.
Here's part of the codes for the method "login" in a class called "HomePage":
cout<<"Password: ";
while (loginAttempt < 3){ //The user gets to attempt to type
//the password 3 times
password = receivePassword(); //Receives password from user
if (flatMemberList[match].getPassword()==password){ //Check if the password is correct
cout<<endl<<"Welcome back "<<loginName<< endl; //If correct, display welcome message
return;
}
else{
loginAttempt++; //Record down one failed attempt
cout<<endl<<"Wrong password"<<endl; //If incorrect, display error
cout<<"Please re-enter password: ";
}
}
cout<<"you have exceeded the legal login attempts"<<endl;
exit(1);
Where receivePassword() is a custom method as follows:
//This method is called when the user types in a password
//The terminal's setting is first changed to 'raw' configuration
//The password are taken in one letter at a time
//It outputs to terminal "*" instead of echoing the input
string HomePage::receivePassword(){
termios oldt, newt; //The structs for manipulation
char password[PaswordLength]; //Password held here
int j = 0; //Password index
tcgetattr(STDIN_FILENO, &oldt); //Get configuration details
newt = oldt;
cfmakeraw(&newt); //Set up new 'raw' configuration structure
//Set up new terminal configuration
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
cin.ignore(1000, '\n'); //flush all the buffers
while(true){
password[j] = cin.get();
if( password[j] == '\r' ) { //check if 'enter' key is entered
password[j] = '\0'; //replace cr with null to make C string
break;
}
cout.put('*'); //echo the asterisk
j++;
} ;
//Reset terminal to old configuration
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return password;
}
Thanks in advance
If you think the problem might be elsewhere, let me know, and i'll post the codes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不知道你的具体问题是什么。但是,您可以应用标准调试技术来找出导致问题的部分。
首先,您正在使用终端(
cfmakeraw
、tcsetattr
等)执行奇怪的操作。听起来这可能与问题有关。因此,删除隐藏用户输入的代码,并确保您的程序在密码正常回显到屏幕时正常运行。您应该能够轻松做到这一点。有关
。这通常称为“分而治之”调试技术。如果您删除了您认为有问题的代码,那么问题是否仍然存在可以帮助您确定它是否与您删除的代码有关。
I don't know what your specific problem is. However, you can apply standard debugging techniques to find out which part is causing the problem.
First, you're doing weird things with terminals (
cfmakeraw
,tcsetattr
, etc). It sounds like that might be related to the problem. So, remove the code that hides the user input and make sure your program works when the password is echoed to the screen normally. You should be able to do that easily.After doing this, you can then decide whether your problem is related to:
This is often called the "divide and conquer" debugging technique. If you remove the code that you think is the problem, then whether the problem remains or not can help you decide whether it's related to the code you removed.
我只是在大一第一学期的期末项目中使用了类似的代码集。事实证明,问题出在密码屏蔽本身。
现在我已经删除了这些部件,除了暴露的引脚之外,该程序现在运行良好。
I was just using the similar set of codes for my final project in our 1st term of our freshmen year. It turns out that the problem was coming from the password masking itself.
Now that I have removed those parts, the program now works well other than the pin being exposed.