I'm currently working with a pre-existing C++ code that parses Fortran-output ASCII of floating-point numbers. The Fortran code that produces the values uses 2-digit exponential output. So for extreme values, it will necessarily omit the e
. Changing to 3-digit output in the Fortran is not an option. Thus, I have mixed scientific-formatted values, some with e
and some without. This confounds my C++ parsing and leads to the question:
How can I send a stringstream of the mixed 2/3-digit floating-point values to a C++ array of doubles?
My thought is to write an IO manipulator to take the extracted output from the stringstream of values and search for all -
or +
with a preceding digit and insert (putback
?) an e
so that when it's extracted to a C++ double, it will be registered correctly. However, everything I've tried has lead to bogus values. As close as I've gotten without getting to that point is below.
#include <iostream>
#include <sstream>
std::istream &scrub(std::istream &is) {
std::istream::sentry s(is);
// ???
return is;
}
int main() {
std::istringstream input("+1.01-101 -2.02e+20\n"
"+3.03e+30 -4.04+104");
double vals[4];
for (int i = 0; i < 4; ++i)
input >> scrub >> vals[i];
for (int i = 0; i < 4; ++i)
std::cout << vals[i] << std::endl;
return 0;
}
The current output is:
1.01
-101
-2.02e+20
3.03e+30
because of the missing "e" to let the extractor properly parse into the C++ double. The desired output is:
1.01e-101
-2.02e+20
3.03e+30
4.04e+104
Notes:
- The input stream may be 100s MBs to GBs, which is why streams were chosen as away to interact with the data rather than large string objects (perhaps with regular expression adjustment).
- I cannot move away from the
input >> vals[i]
approach because doing so will lead to substantial rewriting of the remaining C++ in the actual application. - C++11 capabilities are available to me, but I (unfortunately) cannot go to a newer standard.
Related:
- How to read FORTRAN formatted numbers in C++, but this deals with uniformly formatted values and STL containers, where I (think I) need to stay with a stream to permit using
input >> vals[i]
. - Scientific `d` notation not read in C++, similar to and references prior item.