-2

我正在开发一个具有注册系统的程序,您可以在其中注册新成员。

为了提供一些上下文,您注册的名称必须与现有名称不同,只能是一个单词,并且在保存到文件之前变成全部大写。为了避免文件处理中的潜在错误,我只希望用户名是字母,没有数字或特殊字符。

因为我想避免用户可能意外输入的前导和尾随空格,所以我决定将注册的新用户名存储到 char 数组newName中,但我无法弄清楚如何正确地通过 char 数组来检查任何数字或特殊字符,以便我可以要求用户输入正确的用户名。我尝试过使用不同的循环变体和isalpha()函数,但还没有找到任何东西。

这是我的代码的那部分,到目前为止,"sorry, wrong username"无论我输入带有数字/特殊字符还是仅字母的用户名,它都只说明:

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;
}
4

1 回答 1

1

主要问题是您char[]对字符串使用 C 样式。在 C++ 中,我们使用std::string字符串的数据类型。std::string与样式字符串相比,它的优势是什么,很难理解,为什么有人仍然想使用旧的东西。

结果,您遇到了现在面临的问题。您正在使用魔术常数 80 来定义 char 数组。您还在循环中使用硬编码的数字 80,因此如果您在一个地方更改 80,您可能会在其他地方忘记它。并遇到麻烦。

然后,接下来,这就是您的问题的根本原因,如果您输入的名称少于 80 个字符,将会发生什么。

示例:您输入“迈克”。这是 4 个字母和一个尾随 0。所以,总共 5 个字符。在这 5 个字母之后,这 5 个相关字母之后的剩余数组位置将出现随机垃圾。

但是您的循环始终运行到 80。因此,在检查了前几个正确字符之后,您将继续检查垃圾。然后你在你的第一个循环中得到随机结果。

如果你想解决这个问题,那么你还应该使用 C-Stylestrlen函数来获取字符串的长度。然后你应该循环到这个值。

就像是:

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

这将解决您的问题。

但再次建议:请考虑使用std::string

于 2022-01-11T08:52:14.657 回答