【问题标题】:read/write vector of custom objects to/from file从文件读取/写入自定义对象的向量
【发布时间】:2015-01-28 09:08:31
【问题描述】:

我正在编写代码以将“人”对象的向量写入文件,然后读取该文件。我得到了正确的输出,但是在 main() 函数结束时我得到了错误“未处理的异常写入位置......” 我在做什么错,如何调试这样的错误? 这是我的代码:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

class person{
public:
    string name;
    int age;


 person(){

 }
 person(string name,int age){
     this->name= name;
     this->age = age;

 }

  virtual void display(){

       cout << name <<" "<< age << endl;
  }

};



int main () {

fstream f;
f.open("amu.txt",ios::in | ios::out | ios::trunc);
if(f){
    cout<<"file found"<<endl;
}
else{
    cout<<"file not found"<<endl;
    terminate();
}

// creating a vector
vector<person> per;

//populating with "person" objects

for(int i=0;i<100;i=i+10)
{
    person amu("ameykamat",i);
    per.push_back(amu);
}

//wrting objects from vector to the file

for(vector<person>::iterator itr = per.begin(); itr != per.end() ; ++itr)
    {

    f.write((char *)&(*itr),sizeof(*itr));

    }

// taking curson to the start of the file

    f.seekg(0,ios::beg);

//creating temp obj for printing from file
    person amu;
    while(f.read((char *)&amu, sizeof(amu))){
    cout<<(amu.name).c_str()<<" "<<(amu.age)<<endl;
}


   f.close();

system("pause");

  return 0;
}

【问题讨论】:

  • person 不能轻易复制,这是行不通的。
  • “可简单复制”是什么意思?
  • f.write((char *)&amp;(*itr),sizeof(*itr)); 从根本上被破坏了,因为每个person 对象中的std::string name 成员可能包含指向实际存储文本内容的动态分配(“堆”)内存的指针。您保存指针值,但如果您从另一个进程(甚至是同一程序的另一个实例/运行)重新加载指针值,则字符串内容将不会出现在这些虚拟地址处。将文本本身保存到文件 ala 中:f &lt;&lt; itr-&gt;age &lt;&lt; ' ' &lt;&lt; itr-&gt;name &lt;&lt; '\n;', then read ala while (f >> amu.age && std::getline(f, amu.name)) ...use amu...`.

标签: c++ file vector


【解决方案1】:

std::string 如果不是简单的char[] :没有任何证据证明当您从其地址复制长度为 sizeof(std::string) 时,您实际上复制了数据。标准实现使用动态分配,因此您几乎可以确定不会以这种方式复制实际数据!

您应该设想一种序列化格式(例如:年龄、姓名长度、姓名的空终止字符数组),但您还应该在 C++ 常见问题解答中的 Serialization and Unserialization 处查找参考。

如果它只能在一台机器(或相同类型的机器)和相同的编译器(即没有架构更改问题)上运行,您可以这样实现:

class person {
   ...
    ostream& write(ostream& os) {
        int l = name.length();
        os.write((const char *) &age, sizeof(age));
        os.write((const char *) &l, sizeof(size_t));
        os.write(name.c_str(), name.length());
        return os;
    }

    istream& read(istream& is) {
        int l;
        is.read((char *) &age, sizeof(age));
        if(! is.eof()) {
            is.read((char *) &l, sizeof(size_t));
            if (! is.eof()) {
                char* n = new char[l];
                is.read(n, l);
                name.assign(n,l);
                delete[] n;
            }
        }
        return is;
    }
}

然后使用:

for(vector<person>::iterator itr = per.begin(); itr != per.end() ; ++itr)
    {
    itr->write(f);
    }
...
while(! amu.read(f).eof()){
    cout<<(amu.name).c_str()<<" "<<(amu.age)<<endl;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    • 2013-01-28
    • 2012-10-05
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    相关资源
    最近更新 更多