How to use 'fixed' floatfield for istream/istringstream?

余生颓废 提交于 2020-01-02 03:26:10

问题


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, leaving e 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!