1

I'm trying to write validation for a string that follow the following guidelines:

  1. Can be alphabet

  2. Can be '.' or ','

  3. Can have a space

  4. CAN'T be blank

So for example, "Bob", "Bob Smith", and "Bob Smith, Jr." should be fine, while " " or just hitting the enter key shouldn't.

If the string follows these guidelines the function should simply return it, but if it doesn't it should continue looping through until a correct entry is entered.

I've tried a few different ways of looping through to validate, and if I'm understanding break correctly, I believe this structure should work. That said, entering a simple string such as "Bob" is failing the tests. I'm also unsure how to make sure the user can't just hit the space bar or press enter.

std::string patronName()
    {
        std::string name;
        bool loopFlag = true;

        do
        {
            std::cout << "Please enter the name of the Patron: ";
            std::getline(std::cin, name);

            for (int i = 0; i < name.length(); i++)
            {
                if (!isalpha(name[i]) || !ispunct(name[i]) || !isspace(name[i]) || name.empty())
                {
                    std::cout << "Invalid name entry." << std::endl;
                    break; //If we're invalid, doesn't matter what the rest is
                }
                loopFlag = false;
            }

        }
        while(loopFlag);

        return name;
    }

Are there any obvious errors I'm missing in my logic?

  • As explained below: ***do not*** pass plain `char` to `isspace`/`isalpha`/... First cast to `unsigned char`, otherwise it's undefined behavior for negative characters (i.e. >127). – Matteo Italia May 03 '19 at 06:15

1 Answers1

3

If char is not a alpha or it is not puctuation or it is not a spece then it is invalid.

The letter c is not a space therefore your condition is met.

Try && instead of ||. If char is not a alpha AND it is not puctuation AND it is not a space then it is invalid.

I would look at refactoring your code to separate the validation from other code.

bool isValid(const std::string& str)
{
    // Assume the string is valid - up to us to prove it is not...
    bool result = true;
    // Assume the stringis all spaces - up to us to mark when we see a valid non whitespace
    bool allSpaces = true;

    size_t len = str.length();
    for(size_t i = 0; i < len; i++)
    {
        unsigned char ch = (unsigned char)str[i];
        // alpha and punctuation are ok and mean that the string has
        // something other than a space.
        if (isalpha(ch) || ispunct(ch))
        {
          allSpaces = false;
          continue;
        }
        // space is ok - as long as we have something else too...
        if (isspace(ch))
        {
            continue;
        }
        // not a space, allowed punctuation or an alpha ?
        // must be an error!
        result = false;
        break;
    }
    if (allSpaces)
    {
        result = false;
    }
    return result;
}

See This answer for information on why cast to unsigned char is recommended.

John3136
  • 28,809
  • 4
  • 51
  • 69
  • Ah, stupid mistake. Thank you! As for validating that the entered name is not simply blank, empty() seems to be insufficient. The console is not accepting enter or space followed by an enter. I need it to accept those two, but also flag them so they don't pass the test. – Carl Artino May 03 '19 at 03:24
  • ***Do not*** pass plain `char` to `isspace`/`isalpha`/... First cast to `unsigned char`, otherwise it's undefined behavior for negative characters (i.e. >127). – Matteo Italia May 03 '19 at 06:15