I'm trying to read as many std::complex<double>
as possible from a file (or any std::istream
). If the operation fails, I check for ios::eof(). If it hasn't been set, I assume that there was an error in parsing the data, and I can report to the user that the input file has errors. This scheme works for double, but somehow it fails on complex numbers. Why?
Here is some code to reproduce the problem:
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;
The output is
val = (4,0)
val = (1.2,0)
flags: eof=0 fail=1 bad=0
If I replace std::complex<double>
with double
, it works as expected, yielding
val = 4
val = 1.2
flags: eof=1 fail=1 bad=0
This problem occurs with libstdc++, but it seems to work with libc++:
run on coliru with g++
run on coliru with clang++ and libc++
EDIT I found a bug report from 2013 but the problem still seems to be there, and the library is quite common. Is there a way for me to make it work for anybody without having to write my own parser?
It stems from standard wording:
[complex.ops]
12 Effects: Extracts a complex number x of the form: u, (u), or (u,v), where u is the real part and v is the imaginary part (27.7.2.2).
13 Requires: The input values shall be convertible toT
. If bad input is encountered, callsis.setstate(ios_base::failbit)
(which may throwios::failure
(27.5.5.4)).
14 Returns:is
.
15 Remarks: This extraction is performed as a series of simpler extractions. Therefore, the skipping of whitespace is specified to be the same for each of the simpler extractions.
In particular it does not specify that it should set eofbit
in any case. Even remark does not specify what operations are performed and what their semantic is. There is a Defect Report about it, which suggest resolution by specifying semantic of operation and, if we are lucky, it will make its way to C++17.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With