从文件读取时读取访问冲突

Read Access Violation when reading from file

本文关键字:读取 访问冲突 文件      更新时间:2023-10-16

我正在尝试从我已经将 Person 对象写入的 Person.txt 文件中读取。我收到此错误:引发异常:读取访问冲突。_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;
};

Person类有std::string成员,这些成员包含指向存储在内存中其他位置的动态分配数据的指针。 因此,您将无法使用ofstream::write()写入/读取Person对象,并按照您尝试的方式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;
}