我正在尝试从文件(或任何std::complex<double>
)中尽可能多地阅读std::istream
。如果操作失败,我检查ios :: eof()。如果尚未设置,我认为解析数据时出错,我可以向用户报告输入文件有错误。这种方案适用于双重,但不知何故它在复数上失败。为什么呢?
以下是一些重现问题的代码:
std::istringstream istr("4 1.2");
std::complex<double> val;
while( istr >> val )
std::cout << " val = " << val << std::endl;
std::cout << "flags: eof=" << istr.eof() << " fail=" << istr.fail() << " bad=" << istr.bad() << std::endl;
输出
val = (4,0)
val = (1.2,0)
flags: eof=0 fail=1 bad=0
如果我将std::complex<double>
替换为double
,它会按预期工作,产生
val = 4
val = 1.2
flags: eof=1 fail=1 bad=0
libstdc ++会出现此问题,但它似乎与libc ++一起使用:
run on coliru with clang++ and libc++
编辑我从2013年发现了一个bug report,但问题似乎仍然存在,而且这个库很常见。有没有办法让我可以让任何人都可以使用自己的解析器?
答案 0 :(得分:1)
源于标准措辞:
<强> [complex.ops] 强>
12 效果:提取表单的复数 x : u , (u)或(u,v),其中 u 是真实的部分, v 是虚构的part(27.7.2.2)。
13 需要:输入值应可转换为T
。如果遇到输入错误,请拨打is.setstate(ios_base::failbit)
(可能会抛出ios::failure
(27.5.5.4)。) 14 退货:is
。
15 备注:此提取是作为一系列更简单的提取执行的。因此,对于每个更简单的提取,指定空白的跳过是相同的。
特别是它没有指定在任何情况下都应该设置eofbit
。甚至注释也没有指定执行什么操作以及它们的语义是什么。关于它有一个Defect Report,它通过指定操作的语义建议解决,如果幸运的话,它将进入C ++ 17。