Хотя цикл не читает весь файл ifstream - PullRequest
0 голосов
/ 05 октября 2018

Моя функция 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;
}

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

На мой взгляд, лучшее решение этой проблемы - просто полностью ее избежать.

Вместо одной функции, которая пытается прочитать весь файл, я бы написал функцию, которая просто читает одну запись.Затем вызывайте эту функцию несколько раз, пока весь файл не будет прочитан.Чтобы соответствовать тому, как работает остальная часть стандартной библиотеки, функция для чтения одной записи должна называться operator>>.Он должен получить ссылку 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;
}

Лично я, вероятно, оттуда внесу пару изменений.Я бы сделал 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), {}};
0 голосов
/ 05 октября 2018
for (int j = 0; j < gRecs->NumSubjects; j++) {

должно быть

for (int j = 0; j < gRecs[i].NumSubjects; j++) {
...