一点背景 - 我是学习C ++的新手。我正在使用 Accelerated C ++ 并继续学习。在第4章中,我所获得的代码并没有像书中所说的那样完成,我已经仔细检查了所有代码,以确保我没有输入错误的内容从他们的例子(我无论如何都看不到任何错误)。
我有以下结构和两个函数:
struct Student {
std::string name;
double midtermGrade, finalGrade;
std::vector<double>homework;
};
std::istream& read(std::istream& is, Student& s) {
is >> s.name >> s.midtermGrade >> s.finalGrade;
std::cout << std::endl << "Name: " << s.name << std::endl
<< " - Md: " << s.midtermGrade << std::endl
<< " - Fn: " << s.finalGrade << std::endl;
read_hw(is, s.homework);
return is;
}
std::istream& read_hw(std::istream& in, std::vector<double>& hw) {
if (in) {
hw.clear();
double h;
while (in >> h) {
std::cout << " - Hw: " << h << std::endl;
hw.push_back(h);
}
in.clear();
}
return in;
}
在int main()
我正在调用这样的代码:
Student record;
while (read(std::cin, record)) {
如果我编译并运行,然后粘贴(或键入)以下输入,我得到以下输出:
// Input
Johnny 70 80 50 Fred 95 90 100 Joe 40 40 50
// Output
Name: Johnny
- Md: 70
- Fn: 80
- Hw: 50
Name: red
- Md: 95
- Fn: 90
- Hw: 100
Name: Joe
- Md: 40
- Fn: 40
- Hw: 50
正如你所看到的,&#34;弗雷德&#34;已成为&#34; red&#34;。我用一大堆名字试过这个;任何以A-F开头的东西都会受到同一问题的影响,这使我怀疑它可能是一个十六进制问题。然而,&#34;尼克&#34;成为&#34; k&#34;和&#34; Xander&#34;简单地变成&#34; r&#34;。
我完全不知所措。你知道发生了什么吗?
根据要求,这是一个MCVE:
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
struct Student {
std::string name;
double midtermGrade, finalGrade;
std::vector<double>homework;
};
std::istream& read_hw(std::istream& in, std::vector<double>& hw) {
if (in) {
hw.clear();
double h;
while (in >> h) {
std::cout << " - Hw: " << h << std::endl;
hw.push_back(h);
}
in.clear();
}
return in;
}
std::istream& read(std::istream& is, Student& s) {
is >> s.name >> s.midtermGrade >> s.finalGrade;
std::cout << std::endl << "Name: " << s.name << std::endl
<< " - Md: " << s.midtermGrade << std::endl
<< " - Fn: " << s.finalGrade << std::endl;
read_hw(is, s.homework);
return is;
}
int main()
{
Student record;
std::vector<Student> students;
while (read(std::cin, record)) {}
return 0;
}
答案 0 :(得分:3)
进一步研究后,libc++
似乎没有按照您的方式从cin
读取双打。我不确定它是否只是特别加倍,但我认为可能是。它似乎只影响OSX上的Clang编译器,它的真的令人讨厌:P
对于TL; DR版本,请参阅David已接受的答案。
我目前尚未发现任何良好修复程序,但如果您添加编译器标记-stdlib=libstdc++
,则可以强制它使用较旧的,已弃用的stdlib按预期工作。显然它的功能较少(在我的示例中,std::sort
和std::domain_error
缺失)。其他选项包括不使用double
并对输入进行进一步解析(尽管我不熟悉C ++,但我并不喜欢那个我害怕的人)。 / p>
相关阅读:
official bug report于3。5年前开放,但仍未解决。
答案 1 :(得分:2)
如果您对如何决定某事是否为double
有特定要求,则必须编写实现这些要求的代码。该标准允许丢弃任何可能属于有效浮点表示的前导字符。字母喜欢&#34; e&#34;,&#34; i&#34;,&#34; n&#34;和&#34; f&#34;可以是有效浮点表示的一部分。
为什么这种编码永远不是一个好主意,请参阅Falsehoods Programmers Believe About Names,特别是15号。