我正在尝试编写一个程序来使用struct数组做各种事情,而且我遇到了函数问题。我一直收到错误E2235“必须在函数读取(student *,int)中调用成员函数或其地址”,我不确定是什么导致了这个错误。我的代码如下:
#include <iostream.h>
#include <fstream>
struct student{
string first;
string last;
string id;
double GPA;
int age;
};
void menu();
void read(student* data, int x);
int main(){
bool quit=false;
char choice;
student data[20];
cout<<"Welcome!"<<endl;
//the program is menu driven, so a switch statement allows for many choices
while(!quit){
menu();
cin>>choice;
switch(choice){
case '1': read(data, 20); break;
case '2': break;
case '3': break;
case '4': break;
case '5': break;
case '6': break;
case '7': break;
case '8': cout<<endl<<"Goodbye!\n"; quit=true; break;
default: cout<<"I think you're doing it wrong. Please try again.";
}
}
}
//menu output so the user knows what they're doing
void menu(){
cout<<endl;
cout<<"What would you like to do?"<<endl;
cout<<"(1) - Read data into the database"<<endl;
cout<<"(2) - Add a student"<<endl;
cout<<"(3) - Remove a student"<<endl;
cout<<"(4) - List all students"<<endl;
cout<<"(5) - Compute the average GPA and SD of the database"<<endl;
cout<<"(6) - View Student Information"<<endl;
cout<<"(7) - Save the database"<<endl;
cout<<"(8) - Exit"<<endl;
}
//the problem function
void read(student* data, int x){
ifstream infile;
infile.open("StudentStruct.txt");
int k=0;
string first, last, id;
double GPA;
int age;
while(!infile.eof&&k<x){
infile>>first;
data[k].first;
infile>>last;
data[k].last;
infile>>id;
data[k].id;
infile>>GPA;
data[k].GPA;
infile>>id;
data[k].age;
k++;
}
cout<<"The database now contains "<<k<<" data entries from 'StudentStruct.txt'"<<endl;
}
导致此错误的原因是什么,我应该如何解决?
答案 0 :(得分:2)
我会将问题功能分解为几个单独的部分。一个人只是从文件中读取一条“记录”。另一个会用它来读取所有记录。按照惯例,第一个名为operator>>
(又名“流提取器”):
std::istream &operator>>(std::istream &infile, student &d) {
infile >> d.first;
infile >> d.last;
infile >> d.id;
infile >> d.GPA;
infile >> d.age;
return infile;
}
第二个函数使用该函数读取文件中的所有数据。对于它,你不想要使用while (!whatever.eof())
- 这几乎可以保证失败。有几种选择。一个是:
while (infile >> some_student)
students.push_back(some_student);
另一种可能性是使用istream_iterator
,这可以使整个循环自动化:
std::vector<student> students((std::istream_iterator<student>(infile)),
std::istream_iterator<student>());
定义students
向量,并从istream_iterator
对中初始化它,它隐式循环遍历文件,读取所有数据(使用上面的流提取器。
正如这意味着,我还会使用std::vector<student>
(如果可能)而不是student *
,因此可以在需要时调整大小以适应数据。使用这些,函数变成这样:
std::vector<student> read() {
std::ifstream infile("StudentStruct.txt");
std::vector<student> students((std::istream_iterator<student>(infile)),
std::istream_iterator<student>());
return students;
}
答案 1 :(得分:1)
我认为这是一个与while
条件内的代码相关的笨拙的错误消息,infile.eof
。您没有使用函数调用约定(即infile.eof()
),因此编译器不知道您要对该代码执行的操作:调用成员函数或获取其地址。所以它会引发警告。
从文件中读取学生数据的方式还有另一个问题:
string first, last, id;
double GPA;
int age;
while(!infile.eof&&k<x){
// Here you read a string into the local variable 'first'
infile>>first;
// And here you do... what? referencing the 'first' member variable of the k'th student.
data[k].first;
// Rinse, lather repeat
infile>>last;
data[k].last;
infile>>id;
data[k].id;
infile>>GPA;
data[k].GPA;
infile>>id;
data[k].age;
k++;
}
仔细看看你在做什么:你的data
从未填充过学生。您将值读入局部变量然后抛出结果,从不使用它们。整合克里斯关于取消使用infile.eof()
的建议,请尝试这样做:
while((k < x) && (infile >> data[k].first))
{
infile >> data[k].last;
infile >> data[k].id;
infile >> data[k].GPA;
infile >> data[k].age;
k++;
}