Search code examples
c++stringauthenticationif-statementuser-input

C++: goto and user input not working together


I am working on C++, and using a basic authentication method using if statements, so what I have here, is when the the input is not the desired combination, it will say Access denied and ask the user if they want to try again or quit. I tried doing this using the goto variable, but it hasn't been working. Help please? (Full code: https://pastebin.com/49LdGgJX)

    else {
    cout << "Access denied..." << " Try again? (Y/N) >" << flush;
    string ask;
    cin >> ask;
    if(ask == "N" || "n"){
      cout << "Shutting down..." << endl;
      goto end;
    }
    else if(ask == "Y" || "y"){
      goto restart;
    }

    else {
      cout << "Invalid option." << endl;
      goto restart;
    }
  }

  end:
  return 0;

Solution

  • One of the possible break-ups of that code structure into more procedural way (wouldn't dare to call this "object oriented"). You can use similar way to break up menu handling code into separate functions for each option, etc.

    If this would be multi-user app, then you may want to store instead of simple true/false full credentials of the user authenticated, like having a structure containing name, code (password probably can be thrown away after authentication to not keep it in memory long, if you don't need it later).

    // returns true if user wants to exit
    // sets authenticated to true when the Drew user is detected
    bool AuthenticateUser(bool & authenticated) {
      cout << "Enter your username >" << flush;
      ...
      if (name == "Drew" && ...) {
        authenticated = true;
        cout << "Access granted. Welcome, " << name << "." << endl;
        cout << "Welcome to Database of Drew" << endl;
        return false;
      }
      cout << "Access denied..." << " Try again? (Y/N) >" << flush;
      ...
      return (ask == "N" || ask == "n");  // N = wants to exit
    }
    
    // returns true if user wants to exit
    bool ProceedWithMenu() {
      cout << "1.\tAdd new record." << endl;
      cout << "2.\tDelete record." << endl;
      ...
      if (1 == value) {
        ...
      }
      if (5 == value) {
        cout << "Application quitting... " << endl;
      }
      return (5 == value);
    }
    
    void mainLoop {
      bool authenticated = false;
      bool exitApp = false;
    
      do {
        if (!authenticated) {
          exitApp = AuthenticateUser(authenticated);
        } else {
          exitApp = ProceedWithMenu();
        }
        // repeat authentication / menu until user decides to quit app
      } while (!exitApp);
    }
    

    This example is still quite crude and oversimplified, just trying to illustrate power of do {} while, return, and similar. Often also continue and break can be of great help to control the flow of code execution, without any goto and labels.