• 14
• 12
• 9
• 10
• 9

# Reading/writing vector to file not working

This topic is 3925 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Basically I have a vector of structs and I'm trying to write them out to a file. I"ve actually done this before with no problems but for some reason I keep getting an error when I try to read from the file I write to, most likely because the data isn't being written. This is basically the code:
//For writing to file:
std::ofstream out(L"abc.txt");
out.write(reinterpret_cast<char*>(&one), sizeof(one)); //one is a vector of structs

ifstream in(L"abc.txt");

Either the read or write is not working properly or both aren't working properly.

##### Share on other sites
The memory layout of an std::vector instance is unspecified—only the layout of its contents is.

out.write(reinterpret_cast<char*>(&one.first()), one.size() * sizeof(structure));

##### Share on other sites
Quote:
 Original post by ToohrVykout.write(reinterpret_cast(&one.front()), one.size() * sizeof(structure));

(It should also be possible to do it with std::copy and an ostreambuf_iterator.)

##### Share on other sites
Quote:
Original post by Zahlman
Quote:
 Original post by ToohrVykout.write(reinterpret_cast(&one.front()), one.size() * sizeof(structure));

(It should also be possible to do it with std::copy and an ostreambuf_iterator.)

It is, but you will also need a counting iterator (such as libindustry's n_iterator adaptor) if you don't want to read in the whole file (unless you know of another way -- I wouldn't be surprised):

std::ofstream out( "abc.txt", std::ios::binary );std::copy( one.begin(), one.end(), std::ostreambuf_iterator< char >( out ) )std::ofstream in( "abc.txt", std::ios::binary );std::copy(  industry::make_n_iterator( std::istreambuf_iterator< char >( in ) ),  industry::make_n_iterator( std::istreambuf_iterator< char >(), one.size() ),  one.begin() )

OP: you probably want to use std::ios::binary as well so that \r and \r\n aren't transformed to \n.

jfl.

##### Share on other sites
Quote:
 Original post by jflangloisIt is, but you will also need a counting iterator (such as libindustry's n_iterator adaptor) if you don't want to read in the whole file (unless you know of another way -- I wouldn't be surprised):

If you're relying on external libraries, you may as well use SGI's copy_n instead of std::copy.

##### Share on other sites
And writing structs inside the vector also shouldn't be done with direct memory access. Member alignment and all that.

See this for a general overview of problems:
http://www.parashift.com/c++-faq-lite/serialization.html

Something like this:
struct my_type {  int x;  double y;};void save( std::ostream &s, const my_type &value ) {  s << value.x << value.y;}void load( std::istream &s, my_type &value ) {  s >> value.x >> value.y;}template < class T >void save( std::ostream &s, const std::vector< T > &e ){  s << e.size();  std::vector<T>::const_iterator i = e.begin();  while ( i != e.end() ) {    save( s, (*e) );  }}template < class T >void load( std::ostream &s, std::vector< T > &e ){  int count = 0;  s >> count;  e.clear();  for ( int i = 0; i < count; i++ ) {    T tmp;    load( s, tmp );    e.push_back( tmp );  }}

You then need to provide load/save pairs for every type you wish to support, and every container you use. If you use templates, you can provide generic support for all container types without knowing in advance how they'll be specialized.

Templates also allow a lot of simplification here, but that isn't necessary if you have only a few types.

There's also a small problem with operator precedence (s << x << y), which isn't strictly define. So a completely safe solution would be (s << x; s << y; ), but I never encountered problems using the first syntax.

Also, strings are containers of basic_string type. You need to handle them in the same way as other STL containers, by writing each character out individually. Although they are stored in memory sequentially, this storage isn't specified (especially with unicode), where changing compilation settings could make your serialized files incompatible.

##### Share on other sites
Quote:
 Original post by ToohrVykIf you're relying on external libraries, you may as well use SGI's copy_n instead of std::copy.

Well, the problem with copy_n is that it only stops on the count condition, so you won't be able to deal with EOF or similar issues.