【问题标题】:validation using sstream failing使用 sstream 验证失败
【发布时间】:2016-04-21 11:08:34
【问题描述】:
cout << "\nPlease enter x-ordinate: ";

cin >> test;
stringstream ss(test);
ss >> x;
while(ss.fail())
{
ss.str("");
cin.clear();
cin.ignore(256, '\n');  
cout << "Please enter integer: \n";
cin >> test;
stringstream ss(test);
ss >> x;
cout << x << ss;    
}       

嗨,我正在尝试测试用户的输入是否为整数,通过使用 sstream 来检查它是否可以转换为整数 x,但是一旦我输入了一个有效的整数,while 循环仍然证明是真的,循环继续。有人可以帮忙吗?

【问题讨论】:

    标签: c++ validation integer sstream


    【解决方案1】:

    你的代码有一个小问题......你有两个完全不同的变量同名,一个用于循环条件,一个在循环体内。这两个变量没有任何关系或联系。

    通过设置它的字符串来重用第一个ss变量:

    ...
    cin >> test;
    ss.str(test);
    ...
    

    您也没有清除循环中ss 流的状态,只清除了cin,这就是您的循环永远不会结束的原因。

    我还建议您使用流可以用作布尔条件的事实,并且 operator&gt;&gt; 函数返回对流的引用,然后您可以执行类似的操作

    cout << "\nPlease enter x-ordinate: ";
    getline(cin, test);
    
    istringstream ss(test);
    while(!(ss >> x))
    {
        ss.clear();
        cout << "Please enter integer: \n";
        getline(cin, test);
        ss.str(test);
    }
    

    here for an example of the above


    当然也可以直接使用cin

    int x;
    while (!(cin >> x))
    {
        cin.clear();
        cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
        cout << "Please enter integer: \n";
    }
    

    here for an example of the above

    【讨论】:

    • 让我试试这个然后回复你
    • @user6235245 我刚刚添加了一个注释,因为您没有清除ss 的状态。
    • 你好,我刚试过你的代码,很明显,即使我反复输入1,它仍然停留在“请输入整数”。
    • 这里使用字符串流有什么意义,这个检查不能用cin本身来完成吗?
    • 我尝试使用 cin >> x ,但如果它不是整数类型,程序就会出错
    【解决方案2】:

    没有必要从cin 流式传输到string,创建一个istringstream,然后从那里流式传输到您的号码:它只会为额外类型的错误留出空间,例如"12x" 被视为@ 987654326@ 和 x 被忽略,而不是为用户生成警告/错误消息。

    你可以直接阅读如下:

    const char* prompt = "\nPlease enter x-coordinate: ";
    while (cout << prompt && !(cin >> x))
    {
        cin.clear();
        cin.ignore(256, '\n');  
        prompt = "Please enter integer: \n";
    }
    

    如果不需要更改提示,直接放入循环即可:

    while (cout << "\nPlease enter x-coordinate: " && !(cin >> x))
    {
        cin.clear();
        cin.ignore(256, '\n');  
        std::out << "Please enter an integer.\n";
    }
    

    注意:您会看到有点像您的第一次尝试,其中读取到 string 使用 getline 而不是 &gt;&gt;,这是一个很好的做法,因为它可以让您计算行号(更多对于解析文件比std::cin 有用)并且检查值出现在其他预期数据旁边的行上。看起来像这样:

    std::string line;
    while (std::cout << "Enter coordinate:" &&
           getline(std::cin, line))
    {
        std::istringstream iss(line);
        if (iss >> x)
             break;
        std::cout << "Error - invalid coordinate, please enter an integer\n";
    }
    ...use x...
    

    【讨论】:

    • 非常感谢您的帮助。只是想问一下,因为我对此很陌生。 while (cout > x)) while循环实际执行输出?我认为while循环只检查条件是否为真?这意味着它实际上试图将 cin 放入整数 x 中?
    • 顺便说一句,为了验证整数,当我输入“1asdf”时,它实际上是通过......知道为什么吗?
    • @user6235245:这是因为每个&gt;&gt;输入操作如果能够解析出兼容的输入就成功了,所以从"1asdf"你首先解析出int1,然后它会是下一个 可能失败或检测到问题的解析操作。如果要确保int 后面有空格,可以使用while (cout &lt;&lt; "\nPlease enter x-coordinate: " &amp;&amp; !(cin &gt;&gt; x || !isspace(cin.peek()))) ...std::isspace&lt;cctype&gt; 标头中)。对于getline 版本,if (is &gt;&gt; x &gt;&gt; std::skipws &amp;&amp; is.eof()) break; 用于检测尾随废话。
    • /*while (cout > x) //string leftovers; getline(ISS,剩菜); if (leftovers == "") break; cout
    • @user6235245:我很困惑......你想检查一下,我建议一些东西,你回来告诉我一些完全不同的东西不起作用......? ;-.你试过我的建议了吗?
    【解决方案3】:

    测试变量是什么类型?一个字符串? 您可以尝试将字符串作为输入的通用解析器:

    template<class T>
    bool tryparse(const string word, T& res)
    {
       istringstream parser(word);
       bool status = (parser >> res);
       return status;
    }
    

    【讨论】:

    • test 是一个字符串,当我尝试 cin >> ss (stringstream type) 显然有一个错误
    • 如果 test 是一个字符串并且你想检查它是否可以被解析为一个 int 你可以写: if(tryparse(test, var)) { /* use value in var / } else { / 错误 */ }
    猜你喜欢
    • 2016-08-12
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    • 2012-04-06
    • 2012-05-26
    • 2014-05-24
    相关资源
    最近更新 更多