cin >> i输入错误符号+

haw*_*awk 2 c++ stream cin

在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Ex: 5 1 * 2 4 6 * /   works fine
    5 1 + 2 
          ^ ---> 2 becomes the oprnd here.
Run Code Online (Sandbox Code Playgroud)

什么是一个很好的C++方式来处理这个问题?

Rob*_*obᵩ 5

读入std::strings并使用boost::lexical_cast<>或等效转换它们.

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

后记:如果你对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;
}
Run Code Online (Sandbox Code Playgroud)