c ++使用包含向量的类的随机访问文件

时间:2014-08-05 07:30:17

标签: c++ class serialization vector randomaccessfile

我想从包含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;
}

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

写出一些东西的图像通常不会给你 你可以重读的数据;你需要的事实 reinterpret_cast这样做会警告你,你已经开始了 非常薄的冰。您需要定义文件的格式 想写或使用现有格式(XDR或谷歌) 协议缓冲区,如果你想要二进制文件,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_t与...相同 int。否则,您需要一些额外的边界检查 每个int值。)