我有一个文本文件,我想读入一个结构。
Harry;3.4;3.21;2.83;3.78
Ron;2.89;2.21;2.10;3.33
Hermione;3.65;3.78;4.0;3.89
Dumbledore;2.36;2.75;3.12;3.33
Snape;3.12;2.4;2.78;3.2
这是学生结构。
struct Student
{
string name;
double gpa[4];
double averageGPA;
};
我已经动态分配了Student数组,现在我想从数据中读取文件。使用getline(infile, pointer[0].name, ';');
将获得名字,但我无法读取数字。如果我使用getline(infile, pointer[0].gpa[0], ';');
,我会收到错误消息。我认为它是因为double gpa[4]
不是字符串?我怎样才能读取数据中的数据?
答案 0 :(得分:1)
要读取整数,请使用operator>>
getline(infile, pointer[0].name, ';');
for (int loop = 0; loop < 4; ++loop) {
infile >> pointer[0]. gpa[loop];
// You now need to read the ';' off the input stream
// Note the last number is not followed by a ';'
}
上述代码不会进行任何错误检测。你应该添加它。
通常,struct / class也可以定义自己的输入操作符。
std::istream& operator>>(std::istream& in, Student& data)
{
// do the reading in here.
return str;
}
完成后,您可以轻松阅读stuent
个对象。
int main()
{
Student s1;
std::cin >> s1;
}
答案 1 :(得分:0)
Student
提取运算符如果您要转发到对象,C ++提供了提取运算符作为封装此类功能的方法。 http://msdn.com在此处对提取运算符进行了很好的介绍:https://msdn.microsoft.com/en-us/library/k63a66ec.aspx
但从根本上说,你想写一个看起来像这样的东西:
istream& operator>> (istream& lhs, Student& rhs) {
lhs >> ws;
getline(lhs, rhs.name, ';');
lhs >> rhs.gpa[0];
rhs.averageGPA = rhs.gpa[0];
const auto size = sizeof(rhs.gpa) / sizeof(rhs.gpa[0]);
for(auto i = 1; i < size; ++i) {
lhs.ignore(numeric_limits<streamsize>::max(), ';');
lhs >> rhs.gpa[i];
rhs.averageGPA += rhs.gpa[i];
}
rhs.averageGPA /= size;
}
vector<Student>
而不是动态分配Student[]
vector
提供了许多优势,其中最重要的是基于范围的for
- 循环和iterator
s。
但是在您编写了一个提取运算符之后,您还可以使用istream_iterator
来构造const vector<Student>
。例如:
stringstream in{"Harry;3.4;3.21;2.83;3.78\nRon;2.89;2.21;2.10;3.33\nHermione;3.65;3.78;4.0;3.89\nDumbledore;2.36;2.75;3.12;3.33\nSnape;3.12;2.4;2.78;3.2"};
const vector<Student> data{istream_iterator<Student>{in}, istream_iterator<Student>{}};
您可以看到所有这些的实际示例,包括在data
范围内使用for
- 循环播放:http://ideone.com/iAFE9c
Student.averageGPA
Student.averageGPA
是应根据需要计算的派生数据。将其作为Student
的一部分维护以询问同步问题,可能会调用不必要的计算,并使提取运算符复杂化。
您可以在C ++ 17中轻松获得初始化Student s1
的平均GPA:
const auto averageGPA = accumulate(cbegin(s1.gpa), cend(s1.gpa), 0.0) / size(s1.gpa);
或者在C ++ 11中:
const auto size = sizeof(s1.gpa) / sizeof(s1.gpa[0]);
const auto averageGPA = accumulate(s1.gpa, s1.gpa + size, 0.0) / size;
但这样做的重点在于简化了提取操作符:
istream& operator>> (istream& lhs, Student& rhs) {
lhs >> ws;
getline(lhs, rhs.name, ';');
lhs >> rhs.gpa[0];
for(auto i = 1; i < size(rhs.gpa); ++i) {
lhs.ignore(numeric_limits<streamsize>::max(), ';');
lhs >> rhs.gpa[i];
}
}