Я хочу создать некоторый объект из класса, который включает в себя 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;
}
Может кто-нибудь мне помочь?
Написание немного изображения чего-то, как правило, не дает вам
данные, которые вы можете перечитать; тот факт, что вам нужно
reinterpret_cast
для этого следует предупредить вас, что вы на
очень тонкий лед Вам необходимо определить формат файла, который вы
хотите написать или использовать существующий формат (XDR или Google’s
буферы протокола, если вы хотите двоичный файл, XDR намного проще
реализовать, по крайней мере, если вы ограничиваете переносимость для машин с
32-битный двоичный тип дополнения (2) и IEEE с плавающей точкой);
затем отформатируйте свои данные к нему, в char
буфер, а затем написать
тот.
РЕДАКТИРОВАТЬ:
Так как меня попросили привести пример:
Для простоты я отформатирую в буфер; как правило, я бы написал
класс oxdrstream и форматирование непосредственно в выходной поток,
но это включает в себя более сложную обработку ошибок. Я тоже
предположим, что 32-битный 2-й тип дополнения. Это не
гарантировано, и есть системы, где это не так, но
они довольно редки. (Здесь я использую uint32_t
а также int32_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.)