在一个项目中,我正在使用字符串流使用运算符>>读取数值。我现在收到报告,指出如果在数字上附加了其他字符(例如“2i”),则跨不同平台的解析行为不一致。在Linux上使用GCC / VCC / LLVM编译以下示例将得到:

val = 2;失败= 0

据报道,使用GCC或LLVM在iOS上编译并运行它会产生:

val = 0;失败= 1

在这种情况下,标准对运算符(operator)>>的行为怎么说?

---示例代码---------------------------------------------

#include <sstream>
#include <iostream>

int main(int argc, const char **args)
{
  double val;
  std::stringstream ss("2i");
  ss >> val;
  std::cout << "val=" << val << "; fail=" << ss.fail() << std::endl;
  return 0;
}

最佳答案

根据此reference:

因此,无论哪种情况:

  • (如果您的编译器是C++ 11之前的版本,并且读取失败),它将使val的值保持不变,并将failbit标记为0。
  • (如果您的编译器是C++ 11之后的版本,并且读取失败),它将val的值设置为0,并将failbit标记为0。
  • 但是,只要operator>>使用 num_get::get 函数[27.7.2.2.2算术提取器],就可以从流中顺序提取和解析字符,只要它可以将它们解释为适当类型的值的表示即可。
  • 因此,在您的情况下,operator>>将为第一个字符调用num_get::get(即2),并且读取将成功,然后它将继续读取下一个字符(即i)。 i不适合数值,因此num_get::get将失败并且读取将停止。但是,已经读取了有效字符。这些有效字符将被处理并分配给val,其余字符将保留在stringstream中。为了说明这一点,我将举一个例子:
  • #include <sstream>
    #include <iostream>
    #include <string>
    
    int main(int argc, const char **args)
    {
      double val(0.0);
      std::stringstream ss("2i");
    
      ss >> val;
    
      std::cout << "val=" << val << "; fail=" << ss.fail() << std::endl;
    
      std::string str;
      ss >> str;
      std::cout << str << std::endl;
    
      return 0;
    }
    
    输出:

  • 您会看到,如果我再次对std::string使用extract运算符,则会提取字符i
  • 但是,以上内容并未解释为什么您在ios中没有得到相同的行为。
  • 10-08 08:29
    查看更多