问题
C++ has an I/O manipulator called 'fixed' to input/output floating-point numbers in fixed (non-scientific) form. It works fine for output, but I don't understand how to get input working properly.
Consider this example:
#include <sstream>
#include <iostream>
using namespace std;
int main() {
double value;
istringstream("1.4e1") >> fixed >> value;
cout << value << endl;
}
In my opinion, it should work like this. Input stream has some string. When we apply fixed
manipulator on it and try to read a double/float, it should stop on a first character which is not a digit or a dot (dot is not accepted second/third/more times). So, correct output would be 1.4
(we stop processing input when we encounter 'e'
).
Instead, this code outputs 14
. Why? How it works and what is the purpose of fixed
for input streams? How can I read a double from input stream and stop at 'e'
(leave it in input stream)?
回答1:
You should use std::scientific I tried like this:
#include <sstream>
#include <iostream>
using namespace std;
int main() {
double value;
cin >> std::fixed>> std::scientific >> value;
cout << std::scientific<<value << endl;
}
input: 1.4e1 output: 1.400000e+01
回答2:
This question is somewhat misleading. 1.4e1 = 1.4 * 10¹ = 1.4 * 10 = 14
.
[...] it should stop on a first character which is not a digit or a dot (dot is not accepted second/third/more times).
Why would it? The e1
in 1.4e1
is part of the number: without it the meaning is different. You have to read it, if you want to parse it properly.
So, correct output would be 1.4 (we stop processing input when we encounter 'e').
This would apply if you were reading an integral type which "stops" the parsing when a non-digit character ([0-9]) is met or other conditions trigger (such as overflow or underflow).
回答3:
I need to read a value as
1.4
, leavinge
in input stream. Is it possible?
There isn't a standard manipulator for this, I believe that there's a way to define a custom ones, but it would be too complex. I haven't found an answer on how to do that here on SO, I have only found a question about output stream modifier.
Let's move to at least some kind of solution. That would be parsing it yourself:
#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
int main()
{
std::istringstream iss("1.4e1");
double value;
{
std::string s;
while(iss.peek() != 'e' && !std::isspace(iss.peek()))
s.push_back(iss.get());
std::istringstream(s) >> value;
}
std::cout << value << std::endl;
}
来源:https://stackoverflow.com/questions/29656640/how-to-use-fixed-floatfield-for-istream-istringstream