Нарушение прав чтения при чтении из файла - PullRequest
0 голосов
/ 19 июня 2019

Я пытаюсь прочитать файл Person.txt, в который я уже записал объект Person. Я получаю эту ошибку: Возникло исключение: нарушение прав чтения. _Pnext был 0x87E504.

Я пробовал отладку, и она прекрасно выполняет функцию. Ошибка появляется только после завершения функции.

Вот мой код для чтения из файла:

void readFromFile()
{
    ifstream inFile("Person.txt", ios::in);

    Person p2;

    inFile.read(reinterpret_cast<char*>(&p2), sizeof(Person));

    cout << "First Name: " << p2.getFirst() << endl
        << "Last Name: " << p2.getlast() << endl
        << "Gender: " << p2.getgender() << endl
        << "Age: " << p2.getAge() << endl;



}

Персональный класс:

Class Person {
public:
    Person()
    {
        firstName = "N/A";
        lastName = "N/A";
        gender = "N/A";
        age = 0;
    }

    Person(std::string first, std::string last, std::string gender, int age)
    {
        firstName = first;
        lastName = last;
        this->gender = gender;
        this->age = age;
    }

    ~Person()
    {
        std::cout << "Person Destructor" << std::endl;
    }

    void setFirst(std::string first)
    {
        firstName = first;
    }

    std::string getFirst() const
    {
        return firstName;
    }

    void setLast(std::string last)
    {
        lastName = last;
    }

    std::string getlast() const
    {
        return lastName;
    }

    void setGender(std::string gender)
    {
        this->gender = gender;
    }

    std::string getgender() const
    {
        return gender;
    }

    void setAge(int age)
    {
        this-> age = age;
    }

    int getAge() const
    {
        return age;
    }

private:
    std::string firstName;
    std::string lastName;
    std::string gender;
    int age;
};

1 Ответ

1 голос
/ 19 июня 2019

Ваш класс Person имеет std::string членов, которые содержат указатели на динамически размещаемые данные, хранящиеся в другом месте в памяти. Таким образом, вы не сможете писать / читать Person объекты, используя ofstream::write() и ifstream::read() так, как вы пытаетесь это сделать. Вы будете только писать / читать значения указателя, а не фактические символьные данные, на которые указывают. Вместо этого вы должны сериализовать элементы данных по отдельности. Например, в этом примере вы можете просто записать каждую строку в свою строку в текстовом файле, например:

void writeToFile()
{
    ofstream outFile("Person.txt");

    Person p2("Joe", "Smoe", "M", 25);

    //outFile.write(reinterpret_cast<char*>(&p2), sizeof(Person));
    outFile << p2.getFirst() << "\n"
        << p2.getlast() << "\n"
        << p2.getgender() << "\n"
        << p2.getAge() << "\n";
}

void readFromFile()
{
    ifstream inFile("Person.txt");

    Person p2;
    string s;
    int i;

    //inFile.read(reinterpret_cast<char*>(&p2), sizeof(Person));
    getline(inFile, s);
    p2.setFirst(s);
    getline(inFile, s);
    p2.setLast(s);
    getline(inFile, s);
    p2.setGender(s);
    inFile >> i;
    inFile.ignore(numeric_limits<streamsize>::max(), '\n');
    p2.setAge(i);

    cout << "First Name: " << p2.getFirst() << endl
        << "Last Name: " << p2.getlast() << endl
        << "Gender: " << p2.getgender() << endl
        << "Age: " << p2.getAge() << endl;
}

Я бы предложил сделать шаг вперед и переместить логику записи / чтения в сам класс Person:

Class Person {
public:
    Person()
    {
        firstName = "N/A";
        lastName = "N/A";
        gender = "N/A";
        age = 0;
    }

    Person(std::string first, std::string last, std::string gender, int age)
    {
        firstName = first;
        lastName = last;
        this->gender = gender;
        this->age = age;
    }

    ~Person()
    {
        std::cout << "Person Destructor" << std::endl;
    }

    void setFirst(std::string first)
    {
        firstName = first;
    }

    std::string getFirst() const
    {
        return firstName;
    }

    void setLast(std::string last)
    {
        lastName = last;
    }

    std::string getlast() const
    {
        return lastName;
    }

    void setGender(std::string gender)
    {
        this->gender = gender;
    }

    std::string getgender() const
    {
        return gender;
    }

    void setAge(int age)
    {
        this-> age = age;
    }

    int getAge() const
    {
        return age;
    }

    ostream& write(ostream &out) const
    {
        out << firstName << "\n"
            << lastName << "\n"
            << gender << "\n"
            << age << "\n";
        return out;
    }

    istream& read(istream &in)
    {
        getline(in, firstName);
        getline(in, lastName);
        getline(in, gender);
        in >> age;
        in.ignore(numeric_limits<streamsize>::max(), '\n');
        return in;
    }

private:
    std::string firstName;
    std::string lastName;
    std::string gender;
    int age;
};

ostream& operator<<(ostream &out, const Person &p)
{
    return p.write(out);
}

istream& operator>>(istream &in, Person &p)
{
    return p.read(in);
}

Тогда вы можете сделать это:

void writeToFile()
{
    ofstream outFile("Person.txt");

    Person p2("Joe", "Smoe", "M", 25);

    outFile << p2;
}

void readFromFile()
{
    ifstream inFile("Person.txt");

    Person p2;

    inFile >> p2;

    cout << "First Name: " << p2.getFirst() << endl
        << "Last Name: " << p2.getlast() << endl
        << "Gender: " << p2.getgender() << endl
        << "Age: " << p2.getAge() << endl;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...