Как сделать несколько попыток ввода пароля, когда терминал находится в режиме RAW?
Я создаю меню входа в C++
Я хочу дать пользователю 3 попытки ввода пароля до завершения программы.
Мой код работает нормально, если пользователь получает пароль правильно с первого раза. Затем он перейдет в главное меню и т. Д. Тем не менее, если пользователь получает пароль неправильно. Терминал будет работать до:
Login: Fred
Password: ***
Wrong password
Please re-enter password:
После этого ничего не будет отображаться независимо от того, что пользователь вводит. Даже Ctrl-C не может выйти из программы. Мне было интересно, если кто-нибудь знает, что происходит, и может указать мне в правильном направлении.
Вот часть кодов для метода "login" в классе "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;
}
заранее спасибо
Если вы думаете, что проблема может быть в другом месте, дайте мне знать, и я опубликую коды.
2 ответа
Я не знаю, в чем твоя конкретная проблема. Тем не менее, вы можете применить стандартные методы отладки, чтобы выяснить, какая часть вызывает проблему.
Во-первых, вы делаете странные вещи с терминалами (cfmakeraw
, tcsetattr
, так далее). Похоже, это может быть связано с проблемой. Итак, удалите код, скрывающий пользовательский ввод, и убедитесь, что ваша программа работает, когда пароль отображается на экране в обычном режиме. Вы должны быть в состоянии сделать это легко.
После этого вы можете решить, связана ли ваша проблема с:
- код атрибута терминала, который вы удалили, или
- петля пароля, которая остается.
Это часто называют техникой отладки "разделяй и властвуй". Если вы удалите код, который, по вашему мнению, является проблемой, то проблема в том, останется ли проблема или нет, поможет вам решить, связана ли она с кодом, который вы удалили.
Я просто использовал подобный набор кодов для моего финального проекта в наш первый семестр года. Оказывается, проблема была в самой маскировке пароля. Теперь, когда я удалил эти части, программа теперь работает хорошо, кроме выставляемого булавки.