-2

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;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
wawa
  • 127
  • 5
  • 1
    Have you read the "Notes" section here: https://en.cppreference.com/w/cpp/string/byte/isalpha? – littleadv Jan 11 '22 at 01:28
  • 3
    Addition to the comment above, you started from an improper decision of using char arrays. `std::string` and `cin.getline()` are your friends. – 273K Jan 11 '22 at 01:31
  • Unrelated: What benefit are you getting or believe to be getting from `std::cin.sync();`? – user4581301 Jan 11 '22 at 01:42
  • 1
    `for (int i = 0; i < 80; i++)` processes the entire array every time, but what if... What if the user inputs "Bob"? Can you count on what is in the unused portions of the array? For example, is the string's terminating null a valid alpha character? – user4581301 Jan 11 '22 at 01:45

1 Answers1

1

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

A M
  • 14,694
  • 5
  • 19
  • 44