【问题标题】:Using stringstream and an int variable in C++ to verify that input is an int在 C++ 中使用 stringstream 和 int 变量来验证输入是否为 int
【发布时间】:2010-09-08 17:07:25
【问题描述】:
void get_english_input() {
    string input = " ";
    stringstream my_string(input);
    int ft;
    double in;

    while(true) {    
        cout << "Enter an integer value of feet." << endl;
        getline(cin, input);
        my_string << input;
        if(my_string >> ft)
            break;
        cout << "Invalid input! Please try again." << endl;
    }
    cout << "you entered " << ft << " as the int value for feet." << endl;
    /*while(true) {
        cout << "Enter a double value of inches." << endl;
        getline(cin, input);
        my_string << input;
            break;
    cout << "Invalid input! Please try again." << endl;
    }
    cout << "we are done entering english input" << endl;
    cout << "feet = " << ft << endl;
    cout << "inches = " << in << endl;*/
}

此代码应该通过尝试将 my_string 的内容放入 ft​​ 来测试输入是否为整数。如果我输入字母而不是整数,则会收到错误消息“输入无效!请重试”,其中是应该发生的事情。问题是,在我收到该消息一次后,即使下一个输入有效,我也会为之后的每个输入获得它。


有人建议我应该使用 std::cin.clear(); 来清除错误标志。我尝试将它放在 getline() 之前,但并没有改变问题。我是不是用错了?

【问题讨论】:

    标签: c++ validation stringstream


    【解决方案1】:

    您可以重置 my_string 的错误状态:

    my_string.clear();
    my_string.ignore( /* big number of choice */ );
    

    但我认为每次都重新初始化它会更容易:

    while(true) {    
        cout << "Enter an integer value of feet." << endl;
        getline(cin, input);
        stringstream my_string(input);
    

    【讨论】:

    • +1 -- 在这方面,重置cin 的建议并没有太离谱,他们只是使用了错误的流(因为cin 没有进行转换)
    • 非常感谢!看来这已经解决了问题。
    • 这不仅仅是错误状态,每个输入都附加到前一个。 my_string &lt;&lt; input 行将文本附加到缓冲区。
    • @flies:对,我假设my_string 的最终内容被丢弃(实际上应该声明为istringstream),所以我在这方面更改了代码。但是,如果这是一个问题,那么更改会导致编译错误。
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      蛮力解决方案是将您的输入转储到 std::string 中,然后遍历该字符串并检查每个字符是否介于 0 和 9 之间。

      这不是最优雅的方法。但这是简单而愚蠢的。 :-)

      bool isnum(char c)
      {
         if(! ( c <= '9' && c >= '0'))
         {  
             return false;
         }
         return true;
      }
      
      
      bool has_int(std::string &s)
      {
         for( int i = 0; i < s.length(); i++)
         {
            if( ! isnum(s[i])
            {
               return false;
            }
         }
      
         return true;
      }
      

      【讨论】:

        【解决方案4】:

        我觉得

        mystring >> ft
        

        将始终评估为真(如果 mystring 为空,则可能不是)。无论 mystring 是否实际包含数字,该操作仍然有效。

        一个想法是

         size_t found=input.find_first_not_of("0123456789 ");
          if (found!=string::npos)
          {
           cout <<   "Invalid input! Please try again."
          }
        

        改编自here.

        【讨论】:

        • 当我测试这个函数时,如果我输入一个字符,比如'c',我总是得到错误信息(这实际上是最初的问题;错误信息不会消失)。但是,如果我输入一个数字,它将接受并打印输出。
        • 嗯,也许问题是 mystring 需要清除。毕竟,如果您从未成功提取 int 值,则“c”将始终位于 mystring 的开头。您在连续迭代中所做的只是将内容附加到 mystring 的末尾。如果您尝试清除 mystring 如果不成功怎么办?也许有一个字符串垃圾并将 mystring 提取到它,以防它没有提取到 int。
        猜你喜欢
        • 2021-04-11
        • 1970-01-01
        • 2014-04-22
        • 1970-01-01
        • 2015-06-09
        • 2014-12-06
        • 1970-01-01
        • 2012-08-17
        • 2015-02-02
        相关资源
        最近更新 更多