![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Newbie
Join Date: Jun 2006
Posts: 2
Rep Power: 0
![]() |
C++ Binary Input/Output
Hey everybody,
I've got a few problems with binary input/output. I do this in the following way: << output object var1 = ....; std::string var2 = ....; ofstream output( fileName.c_str(), ios::out | ios::binary); output.write( (char*) (&var1), sizeof( var1)); output.write( (char*) (&var2), sizeof( var2)); ...etc... output.close(); >> input object var1 = ...; std::string var2 = ...; ifstream input( fileName.c_str(), ios::in | ios::binary); input.read( (char*) (&var1), sizeof( var1)); input.read( (char*) (&var2), sizeof( var2)); ...etc... input.close(); The 'object' is a class with members like: std::string and some other custom classes. Now this gives me seg faults because of the dynamic strings. So I tried it using the following code: size = var1.byteSize(); output.write( (char*) ( &size), sizeof( int)); output.write( (char*) ( &var1), size); I save the size of each object, but this crashes as well. So my question to all of you is: can you please give me some good directions for binary I/O ? |
|
|
|
|
|
#2 |
|
Professional Programmer
![]() Join Date: Sep 2005
Posts: 419
Rep Power: 4
![]() |
You can't treat non-POD types as a sequence of bytes. Ever. You probably need to create a new member function that returns a byte string which you can use as the argument to write.
__________________
Even if the voices aren't real, they have some pretty good ideas. |
|
|
|
|
|
#3 |
|
Newbie
Join Date: Nov 2005
Posts: 18
Rep Power: 0
![]() |
You are doing alot of things wrong here.
output.write( (char*) (&var1), sizeof( var1)); output.write( (char*) (&var2), sizeof( var2)); (char*)&var1 will return the address of the var1 object, not the string data you want to write. The string class contains alot of data members, one of wich is a pointer to the acutal string with your data. Your method will only output crap data. (char*)var1 would seem better, only problem, the string class does not provide a (char*) conversion operator. It does however have this operator char& operator[]( size_type index ); which you can use to get the first element. sizeof(var1) and sizeof(var2) is exactly the same. It returns the size of the string class, not the string data. use the size method to get the string length. output.write( (char*) (&var1), sizeof( var1)); // wrong outfile.write((char*)&var1[0], var1.size()); // works Ansi C++ does not guarantee that the stl string is stored sequential in memory, however I dont know know of an implementation that does otherwise. So it probarbly will work. But why not just do it like this: outfile << var1 |
|
|
|
|
|
#4 |
|
Newbie
Join Date: Nov 2005
Posts: 18
Rep Power: 0
![]() |
Oops. I thought var1 and var2 were both strings. Anyway, what I said applies to the string type.
|
|
|
|
|
|
#5 |
|
Newbie
Join Date: Jun 2006
Posts: 2
Rep Power: 0
![]() |
Ok, so the best way to do this with objects is to serialise it ? Every class has to have a function that returns a char* that contains all the objects sequential.
|
|
|
|
|
|
#6 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
I think it's fair to ask if you even know what you mean by the term, "binary I/O". I'm relatively sure we don't know what you mean, even if you do.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#7 | |
|
Newbie
Join Date: Nov 2005
Posts: 18
Rep Power: 0
![]() |
Quote:
I have to correct myself a little bit. string has a c_str() (as you used in your code) method that return char*. Your string data is stored sequentialy. I was thinking vectors. I wasnt thinking straight. Anyway, as for your 'object'. I dont know how its designed, what data does it hold. Does it contain dynamic stream of data just like string, if so you can make a (char*) conversion operator. Something like this. operator char*()
{
return data_; // data_ is pointer to your data
}and also a size method, then its easy to write it to disk: output.write( (char*)&var1, var1.size()); If it has many data members you want to write to file, maybe having a write method passing it a ofstream object would be a solution. object::write(ofstrea& file) { // write your data to file here } Perhaps your object only has fixed data member, no allocated shit. you may do like you originaly did: output.write( (char*) (&var1), sizeof( var1)); |
|
|
|
|
|
|
#8 |
|
Professional Programmer
![]() Join Date: Sep 2005
Posts: 419
Rep Power: 4
![]() |
>Ok, so the best way to do this with objects is to serialise it ?
The only way to do this is to serialize it. You said your object contains std::strings and other classes, so it's not POD. You can't pun non-POD types into an array of bytes because you'll be accessing untouchable regions of the data. That could crash immediately if you hit a trap representation, or you could just corrupt everything and it'll crash later. Either way, it doesn't do what you want.
__________________
Even if the voices aren't real, they have some pretty good ideas. |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|