while 循环不读取整个 ifstream 文件
While loop not reading entire ifstream file
我的 ReadFile 函数没有读取我的整个文件。该文件有几行信息,每行都与一名学生有关。
函数(或 while 循环)正在读取前两条记录,然后退出循环。它正在正确读取所有内容,但为什么它不继续读取整个文件(其中有 13 条记录)?
我试过 while(!infile.eof())
但程序甚至 运行 都没有。
这是我的 ReadFile 块:
void ReadFile() {// Reads data file into array
ifstream infile;
infile.open(cTextFileName);
if (!infile.good()) {
cout << "Cant find text data file!" << endl;
exit(1);
}
int i = 0;
int status;
//bool endOfFile = infile.eof();
infile >> gRecs[i].StudentNo;
while (infile) {
infile >> gRecs[i].FirstName;
infile >> gRecs[i].LastName;
infile >> gRecs[i].NumSubjects;
//cout << "ENTERED WHILE LOOP" << endl;
for (int j = 0; j < gRecs->NumSubjects; j++) {
infile >> gRecs[i].Subjects[j].Code;
infile >> status;
if (status == 0) {
gRecs[i].Subjects[j].Status == eEnrolled;
} else if (status == 1) {
gRecs[i].Subjects[j].Status == eProvisional;
} else {
gRecs[i].Subjects[j].Status == eWithdrawn;
}
infile >> gRecs[i].Subjects[j].Mark;
}
i++;
infile >> gRecs[i].StudentNo;
}
gNumRecs = i;
infile.close();
infile.clear();
cout << gNumRecs << " Records read!" << endl;
}
for (int j = 0; j < gRecs->NumSubjects; j++) {
应该是
for (int j = 0; j < gRecs[i].NumSubjects; j++) {
在我看来,解决这个问题的最好方法就是完全避免它。
我会编写一个只读取单个记录的函数,而不是尝试读取整个文件的单个函数。然后重复调用该函数,直到读取整个文件。为了适应标准库其余部分的工作方式,读取单个记录的函数应命名为 operator>>
。它应该收到一个 istream
的引用和一个对记录的引用,以及 return 完成后对 istream
的引用。
std::istream &operator>>(std::istream &is, gRec &record) {
is >> record.FirstName;
is >> record.LastName;
is >> record.NumSubjects;
for (int i=0; i<record.NumSubjects; i++) {
is >> record.subjects[i].code;
int raw_status;
is >> raw_status;
record.subject[i].status = cvt_status(raw_status);
is >> record.mark;
}
return is;
}
就个人而言,我可能会从那里做出一些改变。我会制作一个 Status
、Subject
和 Schedule
,每个都定义了自己的 operator>>
以从文件中读取自己:
class Status {
enum class status { enrolled, provisional, withdrawn } s;
friend std::istream &operator>>(std::istream &is, Status &s) {
int i;
is >> i;
switch (i) {
case 1: s.s = status::enrolled; break;
case 2: s.s = status::provisional; break;
case 3: s.s = status::withdrawn; break;
}
return is;
}
};
class Subject {
int code;
Status status;
int mark;
public:
friend std::istream &operator>>(std::istream &is, Subject &s) {
return is >> s.code >> s.status >> s.mark;
}
};
class Schedule {
std::vector<Subject> classes;
public:
friend std::istream &operator>>(std::istream &is) {
int num;
is >> num;
for (int i=0; i<num; i++) {
Subject temp;
is >> temp;
classes.push_back(temp);
}
return is;
}
};
那么一条记录就是这样的:
class Record {
std::string FirstName, LastName;
Schedule classes;
public:
std::istream &operator>>(std::istream &is, Record &r) {
return is >> r.FirstName >> r.LastName >> r.classes;
}
};
最后,读取包含学生记录的整个文件将是这样的:
std::ifstream infile("filename");
std::vector<Record> records{std::istream_iterator<Record>(infile), {}};
我的 ReadFile 函数没有读取我的整个文件。该文件有几行信息,每行都与一名学生有关。
函数(或 while 循环)正在读取前两条记录,然后退出循环。它正在正确读取所有内容,但为什么它不继续读取整个文件(其中有 13 条记录)?
我试过 while(!infile.eof())
但程序甚至 运行 都没有。
这是我的 ReadFile 块:
void ReadFile() {// Reads data file into array
ifstream infile;
infile.open(cTextFileName);
if (!infile.good()) {
cout << "Cant find text data file!" << endl;
exit(1);
}
int i = 0;
int status;
//bool endOfFile = infile.eof();
infile >> gRecs[i].StudentNo;
while (infile) {
infile >> gRecs[i].FirstName;
infile >> gRecs[i].LastName;
infile >> gRecs[i].NumSubjects;
//cout << "ENTERED WHILE LOOP" << endl;
for (int j = 0; j < gRecs->NumSubjects; j++) {
infile >> gRecs[i].Subjects[j].Code;
infile >> status;
if (status == 0) {
gRecs[i].Subjects[j].Status == eEnrolled;
} else if (status == 1) {
gRecs[i].Subjects[j].Status == eProvisional;
} else {
gRecs[i].Subjects[j].Status == eWithdrawn;
}
infile >> gRecs[i].Subjects[j].Mark;
}
i++;
infile >> gRecs[i].StudentNo;
}
gNumRecs = i;
infile.close();
infile.clear();
cout << gNumRecs << " Records read!" << endl;
}
for (int j = 0; j < gRecs->NumSubjects; j++) {
应该是
for (int j = 0; j < gRecs[i].NumSubjects; j++) {
在我看来,解决这个问题的最好方法就是完全避免它。
我会编写一个只读取单个记录的函数,而不是尝试读取整个文件的单个函数。然后重复调用该函数,直到读取整个文件。为了适应标准库其余部分的工作方式,读取单个记录的函数应命名为 operator>>
。它应该收到一个 istream
的引用和一个对记录的引用,以及 return 完成后对 istream
的引用。
std::istream &operator>>(std::istream &is, gRec &record) {
is >> record.FirstName;
is >> record.LastName;
is >> record.NumSubjects;
for (int i=0; i<record.NumSubjects; i++) {
is >> record.subjects[i].code;
int raw_status;
is >> raw_status;
record.subject[i].status = cvt_status(raw_status);
is >> record.mark;
}
return is;
}
就个人而言,我可能会从那里做出一些改变。我会制作一个 Status
、Subject
和 Schedule
,每个都定义了自己的 operator>>
以从文件中读取自己:
class Status {
enum class status { enrolled, provisional, withdrawn } s;
friend std::istream &operator>>(std::istream &is, Status &s) {
int i;
is >> i;
switch (i) {
case 1: s.s = status::enrolled; break;
case 2: s.s = status::provisional; break;
case 3: s.s = status::withdrawn; break;
}
return is;
}
};
class Subject {
int code;
Status status;
int mark;
public:
friend std::istream &operator>>(std::istream &is, Subject &s) {
return is >> s.code >> s.status >> s.mark;
}
};
class Schedule {
std::vector<Subject> classes;
public:
friend std::istream &operator>>(std::istream &is) {
int num;
is >> num;
for (int i=0; i<num; i++) {
Subject temp;
is >> temp;
classes.push_back(temp);
}
return is;
}
};
那么一条记录就是这样的:
class Record {
std::string FirstName, LastName;
Schedule classes;
public:
std::istream &operator>>(std::istream &is, Record &r) {
return is >> r.FirstName >> r.LastName >> r.classes;
}
};
最后,读取包含学生记录的整个文件将是这样的:
std::ifstream infile("filename");
std::vector<Record> records{std::istream_iterator<Record>(infile), {}};