【问题标题】:c++ use random access file with class that include a vectorc++ 使用包含向量的类的随机访问文件
【发布时间】:2014-09-27 19:03:00
【问题描述】:

我想从一个包含vector<int> 的类中创建一些对象,并且我想将该对象保存在一个文件中并下次从该文件中读取,但程序没有正确读取新对象中的类数据那个班的。

例如,它可以读取我的向量的大小(即 500),但它无法读取向量单元格的值!有时,当我的文件包含几个或更多对象时,程序会终止并且不打印任何内容。

class my_class {
    int counter;
    vector<int> v;
public:
    my_class():counter(0),v(500,0){}
    void fill_vec(int x) {
        v.at(counter++)=x;
    }

    const vector<int> & get_vec () const {
        return v;
    }

    const my_class & operator=(const my_class &inp){
        v=inp.v;
        counter=inp.counter;
    return *this;
    }
};


void write_to_file(my_class x) {
    fstream opf("/home/rzz/file/my_file.dat", ios::in |ios::out|ios::binary); // my file has been created before - no problem to creat file here
    opf.seekp(0,ios::end);
    opf.write(reinterpret_cast < char *> (&x),sizeof(my_class));
}

my_class read_from_file(int record_number){
    my_class temp;
    fstream opf("/home/rzz/file/my_file.dat", ios::in |ios::out|ios::binary);
    opf.seekg(record_number*sizeof(my_class), ios::beg);
    opf.read(reinterpret_cast< char *> (&temp),sizeof(my_class));
    return temp;
}

int main() {
    my_class zi;
    zi.fill_vec(15);
    write_to_file(zi);
    my_class zi2=read_from_file(0);
    vector<int> vec;
    vec=(zi2.get_vec());
    cout<<zi2.get_vec().size();// right answer , print 500 correctly
    cout<<"first element of vector ( should be 15 ) : "<<vec.at(0);//print 0 here , that is wrong

    return 0;
}

谁能帮帮我?

【问题讨论】:

    标签: c++ class serialization vector randomaccessfile


    【解决方案1】:

    写出一些东西的位图通常不会给你 您可以重读的数据;你需要的事实 reinterpret_cast 这样做应该警告你你正在 很薄的冰。您需要定义文件的格式 想要编写或使用现有格式(XDR 或 Google 的 协议缓冲区,如果你想要二进制,XDR 要简单得多 实施,至少如果您将可移植性限制在具有以下功能的机器上 一个 32 位 2 的补码整数类型和 IEEE 浮点); 然后将您的数据格式化为char缓冲区,然后写入 那个。

    编辑:

    因为有人问我一个例子:

    为简单起见,我将格式化为缓冲区;通常,我会写 oxdrstream 类,并直接格式化为输出流, 但这涉及更复杂的错误处理。我也会 假设一个 32 位 2 的补码整数类型。这不是 保证,并且有些系统并非如此,但是 它们相当罕见。 (在这里,我使用uint32_tint32_t 来 确保代码不会在不支持的系统上编译 支持。)

    void
    insertUInt( std::vector<char>& dest, uint32_t value )
    {
        dest.push_back( (value >> 24) & 0xFF );
        dest.push_back( (value >> 16) & 0xFF );
        dest.push_back( (value >>  8) & 0xFF );
        dest.push_back( (value      ) & 0xFF );
    }
    
    void
    insertInt( std::vector<char>& dest, int32_t value )
    {
        return InsertUInt( dest, static_cast<uint32_t>(value) );
    }
    
    void
    insertIntArray( std::vector<char>& dest, std::vector<int> const& value )
    {
        assert( value.size() <= std::numeric_limits<uint32_t>::max() );
        insertUInt( value.size() );
        for ( int i: value ) {
            insertInt( dest, i );
        }
    }
    

    (这段代码或多或少假设int32_tint。否则,您需要一些额外的边界检查 每个 int 值。)

    【讨论】:

    • 你能解释更多吗?或者请给我一些例子?
    • 再次感谢,不过我理解的有点困难,能否给我一个参考网站或者教程来学习学习一下?
    • 我不知道有任何网站在全球范围内处理主题序列化。在互联网出现之前,我以艰难的方式了解了需要什么。 (回到 C 的时代,fwrite 确实需要 void*;不需要显式转换,我们转储位图像。当我们升级编译器或更改编译器选项时发现我们无法读取它们.) 至于代码本身,你有什么不明白的?一个精确的问题肯定会引出答案。
    • 哦,在互联网创建之前!不明白这一行:(值 >> 24)& 0xFF(你能回复我的电子邮件吗?如果你想要我@trunk.ir)
    • 这是移位运算符,按位和用于掩码。我刚才所说的就足够了如果您了解整数的内部表示。如果你不这样做(并且有可能在不理解它们的情况下做很多好的编程),并且解释需要比我这里更多的空间,en.wikipedia.org/wiki/Bitwise_operation 看起来不错。
    猜你喜欢
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    相关资源
    最近更新 更多