【问题标题】:cin >> i error in input with symbol +cin >> i 输入错误,符号 +
【发布时间】:2012-05-22 03:18:00
【问题描述】:

在一个 C++ 程序中,我尝试处理由整数操作数和运算符 (+ - / *) 组成的用户输入。我可以要求用户在每个运算符之前和之后放置空格。我的方法是假设任何不是 int 的都是运算符。因此,一旦流中出现非 eof 错误,我就会调用 cin.clear() 并将下一个值读入字符串。

#include <iostream>
#include <string>

//in some other .cpp i have these functions defined
void process_operand(int);
void process_operator(string);

using namespace std;

int main()
{
    int oprnd;
    string oprtr;
    for (;; )
    {
        while ( cin >> oprnd)
            process_operand(oprnd);
        if (cin.eof())
            break; 
        cin.clear();
        cin >> oprtr;
        process_operator(oprtr);
    }
}

这适用于 / 和 * 运算符,但不适用于 + - 运算符。原因是operator&gt;&gt; 在报告错误之前吃掉了 + 或 - 并且没有将其放回流中。所以我得到一个无效的令牌读入 optrr。

Ex: 5 1 * 2 4 6 * /   works fine
    5 1 + 2 
          ^ ---> 2 becomes the oprnd here.

什么是处理这个问题的好 C++ 方法?

【问题讨论】:

    标签: c++ stream cin


    【解决方案1】:

    读入std::strings 并使用boost::lexical_cast&lt;&gt; 或其等效项进行转换。

    int main()
    {
        string token;
        while ( cin >> token) {
            try {
                process_operand(boost::lexical_cast<int>(token));
            } catch (std::bad_cast& e) {
                process_operator(token);
            }
        }
    }
    

    后记:如果你对Boost过敏,可以使用lexical_cast的这个实现:

    template <class T, class U>
    T lexical_cast(const U& u) {
      T t;
      std::stringstream s;
      s << u;
      s >> t;
      if( !s )
        throw std::bad_cast();
      if( s.get() != std::stringstream::traits_type::eof() )
        throw std::bad_cast();
      return t;
    }
    

    【讨论】:

      【解决方案2】:

      我认为 >> 认为您正在使用 +/- 开始另一个整数。当你不跟随数字时就会生气。

      正如@Robᵩ 所说,读取一个字符串并进行转换。我只会提供标准库中的另一种选择:

      int stoi(const string& str, size_t *idx = 0, int base = 10);
      

      如果无法执行转换,则抛出 invalid_argument;如果转换后的值超出返回类型的可表示值范围,则抛出 out_of_range

      这是来自The Standard.

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多