如何为 istream/istringstream 使用“固定”浮点域?
Posted
技术标签:
【中文标题】如何为 istream/istringstream 使用“固定”浮点域?【英文标题】:How to use 'fixed' floatfield for istream/istringstream? 【发布时间】:2015-06-21 19:01:12 【问题描述】:C++ 有一个称为“固定”的 I/O 操纵器,用于以固定(非科学)形式输入/输出浮点数。它适用于输出,但我不明白如何让输入正常工作。
考虑这个例子:
#include <sstream>
#include <iostream>
using namespace std;
int main()
double value;
istringstream("1.4e1") >> fixed >> value;
cout << value << endl;
在我看来,它应该像这样工作。输入流有一些字符串。当我们在其上应用fixed
操纵器并尝试读取双精度/浮点数时,它应该停在不是数字或点的第一个字符上(不接受第二/第三/更多次点)。所以,正确的输出应该是1.4
(当我们遇到'e'
时我们会停止处理输入)。
相反,此代码输出14
。为什么?它是如何工作的,fixed
用于输入流的目的是什么?如何从输入流中读取双精度并在 'e'
处停止(将其保留在输入流中)?
【问题讨论】:
std::fixed
对输入流没有任何用途。算术格式化操纵器都不适用于输入流。
@0x499602D2 好的,谢谢。解决方案呢?是否有任何简单的方法(无需编写解析器)来读取双精度,将e
留在输入流中?
显然没有简单的方法。我正在查看提取器的代码,似乎没有办法阻止解析器使用e
或E
。您必须将其读入字符串并自己解析。
@0x499602D2,你能发表你的评论作为答案吗?
【参考方案1】:
你应该使用 std::scientific 我试过这样:
#include <sstream>
#include <iostream>
using namespace std;
int main()
double value;
cin >> std::fixed>> std::scientific >> value;
cout << std::scientific<<value << endl;
输入:1.4e1 输出:1.400000e+01
【讨论】:
不完全是。我需要读取一个值作为1.4
,将e
留在输入流中。有可能吗?【参考方案2】:
这个问题有点误导。 1.4e1 = 1.4 * 10¹ = 1.4 * 10 = 14
。
[...] 它应该停在不是数字或点的第一个字符(点 不接受第二次/第三次/更多次)。
为什么会这样? 1.4e1
中的e1
是数字的部分:没有它,含义就不同了。如果你想正确解析它,你必须阅读它。
所以,正确的输出应该是 1.4(当我们停止处理输入时 遇到'e')。
如果您正在读取整数类型,当遇到非数字字符 ([0-9]) 或触发其他条件(如上溢或下溢)时“停止”解析,这将适用。
【讨论】:
如果我对您的问题的假设是正确的,我们可能会尝试讨论解决方案。 不,我只想阅读1.4
部分并停止。假设我们没有最终的1
,而e
只是表示某个单位的后缀。所以,输入是1.4e
,或1.4euro
。我不需要在数字后读取任何字符到我的号码中,它将转到另一个变量。但我还需要读取双精度数,而不是整数。看起来没有简单的方法可以做到这一点。
我明白了,@JIghtuse。但是e
和euro
是不同的!如果你有1.4 euro
,它会起作用。由于指数必须在尾数旁边,因此可以在它们之间留一个简单的空格。
@Steephen 它与 UDL 无关。
是的,我知道一个空格会改变一切。之后我对阅读 double 和 char 感兴趣,因此在这种情况下,euro
中的 e
是相同的(即,我对第一个之后的字符不感兴趣)。【参考方案3】:
我需要读取
1.4
的值,将e
留在输入流中。有可能吗?
对此没有标准的操纵器,我相信有一种方法可以定义自定义的操纵器,但这太复杂了。我还没有找到关于如何在 SO 上执行此操作的答案,我只找到了 a question about output stream modifier。
让我们至少找到某种解决方案。那将是自己解析它:
#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;
【讨论】:
以上是关于如何为 istream/istringstream 使用“固定”浮点域?的主要内容,如果未能解决你的问题,请参考以下文章