简体   繁体   English

While循环无法读取整个ifstream文件

[英]While loop not reading entire ifstream file

My ReadFile function is not reading my entire file. 我的ReadFile函数无法读取我的整个文件。 The file has lines of information each relating to one student. 该文件包含几行信息,每行信息都与一个学生有关。

The function (or the while loop perhaps) is reading the first two records and then exits the loop. 函数(或while循环)正在读取前两个记录,然后退出循环。 It is reading everything correctly but why does it not continue reading the entire file (which has 13 records in it)? 它可以正确读取所有内容,但是为什么不继续读取整个文件(其中有13条记录)呢?

I've tried while(!infile.eof()) but the program doesn't even run with this. 我已经尝试了while(!infile.eof())但是该程序甚至没有与此一起运行。

Here is my ReadFile block: 这是我的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++) {

In my opinion, the best solution to this problem is to just avoid it completely. 我认为,解决此问题的最佳方法是完全避免它。

Instead of a single function that tries to read the entire file, I would write a function that just reads a single record. 我将编写一个仅读取单个记录的函数,而不是尝试读取整个文件的单个函数。 Then call that function repeatedly until the entire file has been read. 然后重复调用该函数,直到读取了整个文件。 To fit with the way the rest of the standard library works, the function to read a single record should be named operator>> . 为了符合标准库其余部分的工作方式,读取单个记录的功能应命名为operator>> It should receive a reference an istream and a reference to a record, and return the reference to istream when it's done. 它应该收到一个istream引用和一个记录引用,并在完成istream引用返回给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;
}

Personally, I'd probably make a couple changes from there. 就个人而言,我可能会从那里进行一些更改。 I'd make a Status , Subject and Schedule , each of which defines its own operator>> to read itself from a file: 我将创建一个StatusSubjectSchedule ,每个定义一个自己的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;
    }
};

Then a record would be something like this: 那么一条记录将是这样的:

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;
    }
};

And finally, reading an entire file full of student records would be something like this: 最后,读取充满学生记录的整个文件将是这样的:

std::ifstream infile("filename");
std::vector<Record> records{std::istream_iterator<Record>(infile), {}};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM