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
:
- 选择转换说明符,对于
double
即 %lg
- 测试空输入流
- 检查字符串中的下一个字符是否包含在
ctype
or numpunct
facet
s 中
- If
scanf
将允许从 3 获得的字符附加到输入字段,给定在 1[=99 中获得的转换说明符=],如果是3如果不是5是对没有这个字符的输入字段执行
- 接受的输入字段中的
double
被读入
- 如果5失败
failbit
is assigned to the istream
's iostate
,但如果5成功,结果赋给double
- 如果在 3 中
facet numpunct
允许任何千位分隔符进入输入字段,则评估它们的位置,如果它们中的任何一个违反了 grouping
规则facet
中的 failbit
分配给 istream
中的 iostate
- 如果 5 中使用的输入字段为空
eofbit
分配给 istream
的 iostate
对于 double
你真的很关心 scanf
的 %lg
转换说明符提取 double
的规则(其中内部将取决于 strtof
的限制):
- 一个可选的加号或减号
- 以下之一
- "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...?,然后再了解这些不同的库。
我正在尝试使用代码段从 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
:
- 选择转换说明符,对于
double
即%lg
- 测试空输入流
- 检查字符串中的下一个字符是否包含在
ctype
ornumpunct
facet
s 中
- If
scanf
将允许从 3 获得的字符附加到输入字段,给定在 1[=99 中获得的转换说明符=],如果是3如果不是5是对没有这个字符的输入字段执行 - 接受的输入字段中的
double
被读入 - 如果5失败
failbit
is assigned to theistream
'siostate
,但如果5成功,结果赋给double
- 如果在 3 中
facet numpunct
允许任何千位分隔符进入输入字段,则评估它们的位置,如果它们中的任何一个违反了grouping
规则facet
中的failbit
分配给istream
中的iostate
- 如果 5 中使用的输入字段为空
eofbit
分配给istream
的iostate
对于 double
你真的很关心 scanf
的 %lg
转换说明符提取 double
的规则(其中内部将取决于 strtof
的限制):
- 一个可选的加号或减号
- 以下之一
- "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...?,然后再了解这些不同的库。