如何在终端处于 RAW 模式下多次尝试输入密码?

发布于 2024-12-11 09:19:46 字数 3106 浏览 0 评论 0原文

我正在用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

慈悲佛祖 2024-12-18 09:19:46

我不知道你的具体问题是什么。但是,您可以应用标准调试技术来找出导致问题的部分。

首先,您正在使用终端(cfmakerawtcsetattr 等)执行奇怪的操作。听起来这可能与问题有关。因此,删除隐藏用户输入的代码,并确保您的程序在密码正常回显到屏幕时正常运行。您应该能够轻松做到这一点。

有关

  • 执行此操作后,您可以确定您的问题是否与您删除的终端属性代码或
  • 保留的密码循环

。这通常称为“分而治之”调试技术。如果您删除了您认为有问题的代码,那么问题是否仍然存在可以帮助您确定它是否与您删除的代码有关。

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:

  • the terminal attribute code that you removed, or
  • the password loop that remains.

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.

遇见了你 2024-12-18 09:19:46

我只是在大一第一学期的期末项目中使用了类似的代码集。事实证明,问题出在密码屏蔽本身。
现在我已经删除了这些部件,除了暴露的引脚之外,该程序现在运行良好。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文