Search code examples
c++validationiostreamgotoistream

C++ user input restriction with proper retry without "goto"


I have the following code:

qstn:
  cout << "Input customer's lastname: ";
  getline(cin, lname);

  if (lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ") != string::npos) {
      cout << "You can only input alpha here!\n";
      cin.clear();
      goto qstn;
  } else if (lname.empty()) {
      cout << "Please enter your firstname!\n";
      cin.clear();
      goto qstn;
  }

  int lnamel = lname.length();
  int strl = str.length();
  int is = 0;

  for (int i = 1; i < strl;) {
      i++;
      is++;

      if (lname[i] == lname[is] && lname[i] == ' ' || lname[0] == ' ') {
          cin.clear();
          cout << "Please input your lastname properly!\n";
          goto qstn;
      }
  }
  // next question here

I'm having a hard time on thinking what will be the proper logic to avoid the goto statement, since I was college I was using it but someone here said that it's not good to use it at all cause it might ruin my code.

I tried using the do while loop but it's not smooth as goto.

Please help!


Solution

  • Use a function:

    bool getLastName(string & lname,
                     string & str)
    {
        cout << "Input customer's lastname: ";
        getline(cin, lname);
    
        if (lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")
                != string::npos)
        {
            cout << "You can only input alpha here!\n";
            cin.clear();
            return false;
        }
        else if (lname.empty())
        {
            cout << "Please enter your firstname!\n";
            cin.clear();
            return false;
        }
        int lnamel = lname.length();
        int strl = str.length();
        int is = 0;
        for (int i = 1; i < strl;)
        {
            i++;
            is++;
            if (lname[i] == lname[is] && lname[i] == ' ' || lname[0] == ' ')
            {
                cin.clear();
                cout << "Please input your lastname properly!\n";
                return false;
            }
        }
        return true;
    }
    

    All I've done here is replace the gotos with return false. If the program makes it to the end of the function, return true. Make the function call in a while loop:

    while (!getLastName(lname, str))
    {
        // do nothing
    }
    

    Not only does this de-spaghettify the code, but it breaks it up into nice, small, easy to manage pieces. This is called procedural programming.