将文件读取到类对象

时间:2016-07-21 23:25:11

标签: c++ arrays class loops fstream

我无法将文件读取到类对象的成员。它说它无法读取文件。

这是我的班级:

const int SIZE_OF = 5;

class Student
{
public:
    Student();
    Student(const Student &);
    Student(string, int, int, int, int, int);
    friend std::istream& operator >> (std::istream& in, Student& S);
    void display();
private:
    string lastName;
    int grades[SIZE_OF];
};

与我的类对象关联的cpp文件,用于定义函数:

#include "Student.h"

Student::Student()
{
    int i;
    string lastName = "default";
    for (i = 0; i < 5; i++)
    {
        grades[i] = 0;
    }

}

Student::Student(const Student & S)
{
    int i;
    lastName = S.lastName;
    for (i = 0; i < 5; i++)
    {
        grades[i] = S.grades[i];
    }
}

Student::Student(string S, int a, int b, int c, int d, int e)
{
    lastName = S;
    grades[0] = a;
    grades[1] = b;
    grades[2] = c;
    grades[3] = d;
    grades[4] = e;
}

std::istream& operator >> (std::istream& in, Student& S)
{
    char dummy;
    in >> S.lastName >> S.grades[0]
        >> dummy >> S.grades[1]
        >> dummy >> S.grades[2]
        >> dummy >> S.grades[3]
        >> dummy >> S.grades[4];
    return in;

}

void Student::display()
{
    int i;
    int sum = 0;
    double average;
    cout << "Last Name: " << lastName << endl;
    cout << "Grades: " << endl;
    for (i = 0; i < 5; i++)
    {
        cout << grades[i] << endl;
    }
    for (i = 0; i < 5; i++)
    {
        sum = sum + grades[i];
    }
    average = sum / 5;
    cout << "Average: " << average;

}

最后,我到目前为止测试文件打开并将其读取到类中的各种变量的主要功能。

void main()
{
    fstream     File;
    string      FileName = "ProgramSixData.txt";
    bool        FoundFile;
    string      Line;
    Student     testStudent;

    do {
        File.open(FileName, ios_base::in | ios_base::out);
        FoundFile = File.is_open();
        if (!FoundFile)
        {
            cout << "Could not open file named " << FileName << endl;
            File.open(FileName, ios_base::out); // try to create it
            FoundFile = File.is_open();
            if (!FoundFile)
            {
                cout << "Could not create file named " << FileName << endl;
                exit(0);
            }
            else;
        }
        else;
    } while (!FoundFile);
    do {
        File >> testStudent;
        if (File.fail())
        {
            cout << "Read Failed" << endl;
            cout << "Bye" << endl;
            exit(0);
        }
        else;
        testStudent.display();
    } while (!File.eof());
    cout << "Bye" << endl;
    File.close();
}

我正在阅读的文本文件如下:

George
75,85,95,100,44
Peter
100,100,100,100,100
Frank
44,55,66,77,88
Alfred
99,88,77,66,55

如何将每个姓名和相关的5个成绩保存到学生班级的特定对象?

1 个答案:

答案 0 :(得分:0)

你挖得太深了。我为您做了一个示例解决方案,专注于解析。事情可能会更短,我们可以立即让学生而不是按地图方式进行,但我希望您了解如何解析文件,因为这显然是您正在努力解决的问题。如果您不理解,请向我询问有关代码的任何信息。

void main()
{
    string      FileName = "ProgramSixData.txt";
    bool        FoundFile;
    string      Line;
    vector<Student> Students;

    ifstream file(FileName); //an ifstream is an INPUTstream (same as a fstream with ::in flag. Passing the FileName as argument opens that file
    if (file.fail()) //check if the file opened correctly
    {
        cout << "Failed to open inputfile\n";
        return;
    }

    map <string, vector<int>> studentAndGrades; //map is a container that uses keys and values, every key has a value, we will use the name of the student as the key to access his marks (a vector of int)
    vector<string> allLines;
    string line;
    while (file >> line) //these 2 linessimply reads ALL the lines to the allLines vector
        allLines.push_back(line);

    for (size_t i = 0; i < allLines.size(); i += 2) //loop over all lines, by 2 at a time (1 for the students name and 1 for his marks)
    {
        vector<int> numbers;

        size_t lastCommaIdx = 0;
        size_t currentCount = 0;
        string scores(allLines[i + 1]); //make a copy of allLines[i + 1] for convenient use
        bool firstLine = true;
        for (size_t i = 0; i < scores.size(); ++i) //following code is just to split the numbers from the comma's and put them in a vector of int
        {
            if (scores[i] == ',')
            {
                if (firstLine)
                {
                    numbers.push_back(stoi(scores.substr(lastCommaIdx, currentCount)));
                    firstLine = false;
                }
                else
                {
                    numbers.push_back(stoi(scores.substr(lastCommaIdx + 1, currentCount)));
                }
                lastCommaIdx = i;
                currentCount = 0;
            }
            else
            {
                ++currentCount;
            }
        }
        numbers.push_back(stoi(scores.substr(lastCommaIdx + 1))); //last number
        studentAndGrades.insert(make_pair(allLines[i], numbers)); //finally, insert them in the map
    }

    for (const auto& student : studentAndGrades)
        Students.push_back(Student(student.first, student.second[0], student.second[1], student.second[2], student.second[3], student.second[4])); //make students from the information that we read into the map

    for (auto& student : Students) //display all students with a range based for loop
        student.display();
    file.close();
}