将动态数组列表以二进制形式写入文件>

时间:2009-07-08 23:43:18

标签: c++ stl file-io

我想编写一个具有整数id列表的结构。该列表可以具有不同的长度。

typedef  struct ss_iidx_node {
    int totalFreq;
    vector < int > docIDList;
}s_iidx_node;

现在,我希望将此结构写入文件并将其读回。 我该怎么办?

Wrting已经完成:

fwrite(&obj,sizeof(s_iidx_node),1,dat_fd2);

当我读回来时,它会给出垃圾值。它似乎只存储stl向量的strating和结束位置......在读取时它是垃圾? 不知道怎么做

由于

4 个答案:

答案 0 :(得分:3)

您的代码只是不可移植的。它试图将对象视为原始字节序列,对于C ++标准中的非POD对象,这显然是未定义的(并且您的结构是非POD,因为它包含非POD类型的成员std::vector

实践中发生的事情是,矢量类通常由3个字段组成:指向数据开头,大小和容量的指针。你看到的是构成写入文件的那些值的字节。

你应该考虑完全避免使用C风格的文件I / O,而是使用C ++流和Boost Serialization library - 它支持开箱即用的STL集合。

答案 1 :(得分:2)

虽然我宁愿看到基于显式序列化的方法,但您可以尝试:

fwrite(&obj.totalFreq,sizeof(int),1,dat_fd2);
fwrite(&obj.docIDList[0],sizeof(int),obj.totalFreq,dat_fd2);

假设totalFreq == docIDList.size(),它是一个虚假变量,所以更好的实现是:

size_t size=obj.docIDList.size();
fwrite(&size,sizeof(size_t),1,dat_fd2);
fwrite(&obj.docIDList[0],sizeof(int),size,dat_fd2);

我首选的实现方式是:

size_t size=obj.docIDList.size();
fwrite(&size,sizeof(size_t),1,dat_fd2);
for (size_t i=0;i<size;i++)
{
    int id=obj.docIDList[i];
    fwrite(&id,sizeof(int),1,dat_fd2);
}

答案 2 :(得分:2)

矢量类的定义大致如下:

template <typename T>
class vector {
  ...

  T* array; // pointer to the actual data, stored in a dynamically allocated array
  size_t arrayLength;
  ...

};

向量的实际数据存储在动态分配的数组中。 vector类只保存一个指向该数组的指针。所以你的fwrite调用只存储向量类的内容,而不是它指向的数组的内容。

你需要写出矢量的实际元素。

答案 3 :(得分:0)

我在VS2010 Beta1上尝试了这个。没试过其他编译器。请查看。

class Employee
{
    private:
      int _empno;
      string _name;
public:
      Employee(int empno, string name) : _empno(empno), _name(name) { }
      Employee() : _empno(-1), _name("") { }
      virtual ~Employee() { }
      virtual int GetEmpId() const;
      virtual string GetName() const;
      friend ostream& operator<<(ostream& os, const Employee& emp);
};

class Manager : public Employee
{
    private:
      vector<Employee> Reportees;
    public:
      Manager() : Employee() { }
      Manager(int empno, const string& name) : Employee(empno, name) { }
      ~Manager() { }
      void InsertEmployees(const Employee& emp);
      friend ostream& operator<<(ostream& os, const Manager& manger);
};

void Manager::InsertEmployees(const Employee& emp)
{
      Reportees.push_back(emp);
}

ostream& operator<<(ostream& os, const Manager& manager)
{
       os << "Empid:" << manager.GetEmpId()
                << "|Name:" << manager.GetName() << endl;
      typedef vector<Employee>::const_iterator EmpIter;

      EmpIter iter = manager.Reportees.begin();<br>
      for ( ; iter != manager.Reportees.end(); ++iter)
      {
                Employee e = *iter;
                os << "Reportee" << endl;
                os << "Empid:" << e.GetEmpId()
                   << "|Name:" << e.GetName() << endl;
      }    
return os;  
}

int main()
{
ofstream data("data.txt");
ofstream bin_data("data.bin", ios::binary);

Employee e1(100, "Jagan");
Employee e2(101, "Nath");
Employee e3(102, "Sai");
Employee e4(103, "Pantula");

Manager m(104, "Neeraja");
m.InsertEmployees(e1);
m.InsertEmployees(e2);
m.InsertEmployees(e3);
m.InsertEmployees(e4);


data << m;
data.close();
bin_data.write(reinterpret_cast<char*>(&m), sizeof(m));

bin_data.close();
ReadDataFromFile();
bin_data.close();
}

void ReadDataFromFile()
{

ifstream bin_data("data.bin", ios::binary);

Manager m;

while (bin_data.read(reinterpret_cast<char*>(&m), sizeof(m)))
   cout << m;

}