C++ - 从 cin 中读取一个 double,后跟一个字符

C++ - Reading a double, followed by a character, from cin

我正在尝试使用代码段从 cin 中读取一个双精度数,后跟一个字符:

double d;
char c;
while(1) {
    cin >> d >> c;
    cout << d << c << endl;
}

奇怪的是它对某些角色有效,但对其他角色无效。例如,它适用于“2g”、“2h”,但不适用于“2a”、“2b”、“2x”...:[=​​11=]

mwmbp:ppcpp mwisse$ ./a.out

2a
0
2b
0
2c
0
2克
2克
2小时
2小时
2i
0小时
2x
0小时
2z
2z

正如你们其中一位所指出的,它确实适用于整数。你知道为什么它对双打不起作用吗?我至今无法找到有关 cin 如何解释其输入的信息。

目前这是 LLVM 上的一个错误:https://llvm.org/bugs/show_bug.cgi?id=17782 早在 2014 年,它就从 Howard Hinnant 分配给了 Marshall Clow...好吧,不要屏住呼吸,因为它很快就会得到修复。

编辑:

istream extraction operator internally uses num_get::do_get 依次执行这些任务 double:

  1. 选择转换说明符,对于 double%lg
  2. 测试空输入流
  3. 检查字符串中的下一个字符是否包含在 ctype or numpunct facets
  4. If scanf 将允许从 3 获得的字符附加到输入字段,给定在 1[=99 中获得的转换说明符=],如果是3如果不是5是对没有这个字符的输入字段执行
  5. 接受的输入字段中的 double 被读入
  6. 如果5失败failbit is assigned to the istream's iostate,但如果5成功,结果赋给double
  7. 如果在 3facet numpunct 允许任何千位分隔符进入输入字段,则评估它们的位置,如果它们中的任何一个违反了 grouping 规则facet 中的 failbit 分配给 istream 中的 iostate
  8. 如果 5 中使用的输入字段为空 eofbit 分配给 istreamiostate

对于 double 你真的很关心 scanf%lg 转换说明符提取 double 的规则(其中内部将取决于 strtof 的限制):

  1. 一个可选的加号或减号
  2. 以下之一
    • "INF" 或 "INFINITY"(不区分大小写)
    • "NAN"(不区分大小写)
    • “0x”或“0X”,十六进制数字和可选的小数点字符的输入字段,可选地后跟 "p" 或 "P" 加号或减号和 小数 指数
    • 十进制数字和可选的小数点字符以及可选的 "e" 或 "E" 加号或减号和非空指数的输入字段

请注意,如果您的 locale 将任何其他表达式定义为可接受的浮点输入字段,这也被接受。因此,如果您在 istream 中添加了一些特殊的调味料,那么您正在使用的可能就是问题所在。除此之外,尾随的 "a"、"b" 或 "x" 都不是 %lg 转换说明符的可接受后缀,因此您的实现不兼容或者您还有其他原因没告诉我们。

这是您在 gcc5.1 上成功输入的实例,它是兼容的:http://ideone.com/nGGW0L

由于问题是由 libc++ 中的错误(或功能,取决于您的观点)引起的,似乎避免它的最简单方法是改用 libstdc++,直到修复到位。如果您 运行 在 mac 上,请将 -stdlib=libstdc++ 添加到您的编译标志中。 g++ -stdlib=libstdc++ test.cpp 将正确编译此 post.

中给出的代码

Libc++ 似乎还有其他类似的错误,其中之一我在此处 post 编辑:Trying to read lines from an ASCII file using C++ , Ubuntu vs Mac...?,然后再了解这些不同的库。