代码之家  ›  专栏  ›  技术社区  ›  Kapil D

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

  •  0
  • Kapil D  · 技术社区  · 16 年前

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

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

    现在,我想把这个结构写进一个文件,然后再把它读回来。 我该怎么做?

    扭绞完成:

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

    当我读回它时,它给出了垃圾值。似乎它只存储stl向量的分层和结束位置…哪个在读取时是垃圾? 知道怎么做吗

    谢谢

    4 回复  |  直到 16 年前
        1
  •  2
  •   Dave Gamble    16 年前

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

    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
  •  3
  •   Pavel Minaev    16 年前

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

    实际上,Vector类通常由3个字段组成:指向数据开头的指针、大小和容量。您看到的是组成这些写入文件的值的字节。

    应该考虑完全避免C风格文件I/O,并使用C++流和 Boost Serialization library 相反,它支持现成的STL集合。

        3
  •  2
  •   Stack Overflow is garbage    16 年前

    Vector类的定义大致如下:

    template <typename T>
    class vector {
      ...
    
      T* array; // pointer to the actual data, stored in a dynamically allocated array
      size_t arrayLength;
      ...
    
    };
    

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

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

        4
  •  0
  •   Loki Astari    16 年前

    我在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;
    
    }