【问题标题】:Forcing input through validation check通过验证检查强制输入
【发布时间】:2017-07-08 02:09:23
【问题描述】:

我们创建了一个验证检查,以便输入只能是字母字符。虽然它按预期工作,但我的朋友和我都遇到了一个奇怪的症状,即使代码明确(至少对我们而言)不允许他们这样做,您也可以强制通过验证。

运行以下代码,然后按 [enter] 或随机垃圾大约十几次并输入不可接受的输入,例如 321- 将导致程序退出验证。是某种固有的限制还是我们遗漏了代码?

即使在将代码剥离为裸验证后仍会导致症状,尽管根据机器的不同,它似乎确实有不同的限制。一些计算机在 3-4 次暴力破解后让它偷偷溜走,而 c9.io 则经受住了大约一打。

我的验证循环确实看起来很混乱,但我之前也经历过较小的 for 循环。到目前为止,我注意到的唯一相似之处是 getline()

#include<iostream>
#include<string>
#include<fstream>

using namespace std;

//prototypes
void validateUserName(string &name);//validate name

//main function
int main()
{

    //initialize
    ifstream file;

    string username; //holds username which serve as file name


    //first prompt
    cout<< "Enter your name and press <ENTER>";
    getline(cin, username);

    //call functions
    validateUserName(username);
    //begin shutdown
    cout << "good-bye" << endl;
    cin.get();
}




void validateUserName(string &name){
    int errCount = 0;
    int i=0;
    do
    {
        errCount = 0;
        i=0;
        //go thru each character of the name to count non-alphabetic character
        while (name[i])
            {
            if ( !isalpha(name[i]) )
            errCount++;
            i++;
            }

        if (errCount > 0 || name.empty() )
        {
            //prompt user again alerting them of error
            cout << "Invalid entry, try again" << endl;
            getline(cin, name);
        }

    }
    while (errCount > 0 || name.empty() );//the validation loop doesn't end until user enters acceptable entry
    name+=".txt"; //appended file type
}

【问题讨论】:

  • 虽然我不能 100% 说这是您的问题,但对于 while (name[i]),您一直在迭代直到遇到 \0,而不是直到字符串的末尾。因此,您可以在不测试所有字符的情况下退出非空字符串的循环。您应该改用for(char s : name)

标签: c++ validation input


【解决方案1】:

当您从第二个 cin 中出来时,name 不再是空的。所以第二个条件不满足,你退出了主 while 循环。一个快速的解决方法是在最终条件中增加 errCount:

if (errCount > 0 || name.empty() )
{
   errCount++;                                                                                                                                                   
   cout << "Invalid entry, try again" << endl;
   getline(cin, name);
}

虽然这不是您的问题的一部分,但我建议您使用 string::size() 而不是检查空字符。我不认为 getline 添加了这个,所以你可能正在处理未定义的行为。

void validateUserName(string &name)
{
    int errCount = 0;
    do
    {
        errCount = 0;
        //go thru each character of the name to count non-alphabetic character                                                                                                                              
        for (int i = 0; i < name.size() && !name.empty(); i++)
        {
            if ( !isalpha(name[i]) ) 
            {
                errCount++;
                break;
            }
        }

        if (errCount > 0 || name.empty() )
        {
            errCount++;
            //prompt user again alerting them of error                                                                                                                                                      
            cout << "Invalid entry, try again" << endl;
            getline(cin, name);
        }

     }
    while (errCount > 0 || name.empty() );//the validation loop doesn't end until user enters acceptable entry                                                                                              

}

【讨论】:

    猜你喜欢
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    相关资源
    最近更新 更多