【问题标题】:Another istream discrepancy between libstdc++ and libc++libstdc++ 和 libc++ 之间的另一个 istream 差异
【发布时间】:2014-03-06 19:16:47
【问题描述】:

这个简单的代码:

#include <iostream>
#include <sstream>
int main()
{
   float x = 0.0;
   std::stringstream ss("NA");
   ss >> x;

    std::cout << ( ss.eof() ? "is" : "is not") << " at eof; x is " << x << std::endl;
}

根据我选择的库返回不同的结果(我在 OSX 10.9 上从 xcode 5 运行 clang):

clang++ -std=c++11 -stdlib=libstdc++ -> not at eof
clang++ -stdlib=libstdc++ -> not at eof
/usr/bin/g++-4.2 -> not at eof

clang++ -std=c++11 -stdlib=libc++ -> at eof
clang++ -stdlib=libc+ -> at eof

在我看来,如果我尝试将字母字符读入浮点数,操作应该会失败,但它不应该吃掉无效字符 - 所以我应该得到 fail() 而不是 eof(),所以这个看起来像 libc++ 中的一个错误。

在某处是否有描述行为应该是什么的 c++ 标准?

附言我已经像这样扩展了原始测试程序:

#include <iostream>
#include <sstream>
int main()
{
   float x = 0.0;
   std::stringstream ss("NA");
   ss >> x;
    std::cout << "stream " << ( ss.eof() ? "is" : "is not") << " at eof and " << (ss.fail() ? "is" : "is not") << " in fail; x is " << x << std::endl;
    if (ss.fail())
    {
        std::cout << "Clearing fail flag" << std::endl;
        ss.clear();
    }
   char c = 'X';
    ss >> c;
    std::cout << "Read character: \'" << c << "\'" << std::endl;
}

这就是我所看到的:

使用 libc++:

stream is at eof and is in fail; x is 0
Clearing fail flag
Read character: 'X'

使用 stdlibc++:

stream is not at eof and is in fail; x is 0
Clearing fail flag
Read character: 'N'

p.p.s.如问题中所述,n.m.链接到,如果 stringstream 设置为“MA”而不是“NA”,则不会出现问题。显然,libc++ 开始解析字符串,认为它会得到“NAN”,然后当它没有时,它就会变得很不安。

【问题讨论】:

  • 这与here描述的问题相同。
  • nm,我看过那个问题,它看起来非常相似,但由于我的问题是 eof() 而另一个问题抱怨 fail() 我不确定根本问题是否是相同的。查看为其他问题提交的错误,目前尚不清楚修复该错误是否也能解决我的问题......但你知道图书馆的内部运作比我好 100 倍!
  • 这是同一个问题,即NA是否被失败的输入操作消耗

标签: c++ stringstream istream libstdc++ libc++


【解决方案1】:

在这种情况下,你应该得到失败,但不是 eof。基本上,如果, 失败后,您可以清除错误并成功执行 一个字符的get(),你不应该得到eof。 (如果你 在clear()之后无法成功读取字符,是否 您是否获得 eof 可能取决于您尝试的类型 阅读,也许在某些情况下,甚至在实现上。)

【讨论】:

  • 不太清楚。 “NA”是“NAN”的前缀。 libc++ 支持从流中读取“NAN”,libstdc++ 不支持。
  • @n.m.好点。但是,标准是明确的。输入数字类型时,只允许从流中提取集合"0123456789abcdefxABCDEFX+-" 中的字符,加上(取决于语言环境的)小数点和千位分隔符。这可能是一个疏忽(在 C 中,fscanf 允许读取 NaN 和无穷大),但这是标准当前读取的方式。 (从 QoI 的角度来看,如果一个实现决定支持 NaN 和无穷大,它至少应该采取措施确保在没有匹配的情况下不提取字符。或者尝试这样做。
  • @n.m.这应该被认为是标准中的错误吗?也没有P,这可能在输入十六进制浮点时发生。这是一个严重的问题,因为这意味着 fscanf( fin, "%f", &amp;float_value ) 可能会给出与 fin &gt;&gt; float_value 不同的结果(并提取更多字符),即使两者都成功。
  • 是的,当我看到这个列表时,我也立刻想到了“P 在哪里”。我认为这是标准中的错误。
  • @n.m.由于目标是提供与fscanf 相同的可能性,因此不允许NaNInfinity 也是错误的。 (当然,在这种情况下,它在 C++ 中会失败,而不是仅仅给出不同的结果。所以也许意图是让它立即失败,并要求用户然后得到一个单词,然后自己比较。)跨度>
猜你喜欢
  • 2012-02-18
  • 2013-11-12
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 2018-05-10
  • 2013-07-01
  • 2017-09-25
  • 1970-01-01
相关资源
最近更新 更多