Search code examples
c++fileisalpha

Am I using isalpha() function in c++ correctly?


I am working on a program that has a registry system where you can register new members.

To give some context, the name you register has to be different than existing names, can only be one word, and is turned into all caps before being saved to a file. To avoid potential mistakes in file handling, I only want the usernames to be letters, no numbers or special characters.

Because I want to avoid leading and trailing white space the user may accidentally enter, I decided to store the new username being registered into a char array newName, but I just cannot figure out how to properly go through the char array to check for any numbers or special characters so I can ask the user to enter a proper username instead. I've tried using different loop variations with isalpha() function but haven't found anything yet.

Here is that section of my code, which as of now only says "sorry, wrong username" no matter if I enter a username with numbers/special characters or just letters:

char newName[80];
bool valid;

do {
    valid = true;
    std::cin >> newName;
    std::cin.sync();
    for (int i = 0; i < 80; i++) {
        if (!std::isalpha(newName[i]))
           valid = false;
        else
            valid = true; 
    }
    if (!valid)
        std::cout << "Sorry, wrong username." << std::endl;
} while (!valid);
for (int i = 0; i < 80; i ++) {
    if (newName[i] != '\0')
        newName[i] = toupper(newName[i]);
    else
        break;
}
for (int i = 0; i < nameList.size(); i++) {
    if (nameList.at(i) == newName) {
        std::cout << "Sorry, this name already exists. If you are registering a new member, please enter a new name for them." << std::endl;
        validName = false;
        break;
    }
    if (nameList.at(i) !=  newName)
        validName = true;
}

Solution

  • The main problem is that you use C-Style char[] for strings. In C++, we use the datatype std::string for strings. std::string is that superior compared to-Style strings, that it is hard to understand, why anybody wants still to use the old stuff.

    As a consequence you have the problems that you are facing now. You are using a magic constant 80 for the definition of your char array. You also use the number 80 hardcoded in the loops, so that if you change the 80 in one place, you might forget it in other places. And run into trouble.

    Then, next, and that is the root cause of your problems, what will happen, if you enter shorter names than 80 charachters.

    Example: You enter 'Mike'. This are 4 letters and a trailing 0. So, overall 5 characters. After this 5 letters there will be random garbage at the remaining array positions after this 5 relevant letters.

    But your loop runs always until 80. So, after having check the first few correct characters you will continue to check garbage. And then you get random results in your first loop.

    If you want to fix that, then you should also use the C-Style strlen function, to get the length of the string. And then you should loop up to this value.

    Something like:

    int length = strlen(newName);
    for (int i = 0; (i < length) and (i < 80); i++) {
    

    This will solve your problem.

    But again the recomendation: Please consider using std::string