li********@gmail.com wrote:
A int in memory takes 32bits (4 bytes).
But if I use ofstream to save a int like this:
int i=1234567890;
ofstream ofs("c:\\intdata.bin", ios::binary);
ofs<<i;
It becomes 10 bytes in a file.
Is there any way to save a int or double in a more compact way?
Yes. You may start by pondering on the following proof of concept. Error
handling is not done. Untested code -- use at your own risk.
#include <cstring>
#include <iostream>
#include <cstddef>
template < typename POD >
class io_converter {
char the_data [ sizeof(POD) ];
friend
std::ostream & operator<< ( std::ostream & o_str,
io_converter const & ic ) {
o_str.write( ic.the_data, sizeof(POD) );
return ( o_str );
}
friend
std::istream & operator>( std::istream & i_str,
io_converter & ic ) {
i_str.read( ic.the_data, sizeof(POD) );
return ( i_str );
}
public:
io_converter ( void )
{
std::memset( &the_data, 0, sizeof(POD) );
}
io_converter ( POD const & data )
{
get( data );
}
void get ( POD const & data ) {
std::memcpy( &the_data, &data, sizeof(POD) );
}
void put ( POD & data ) const {
std::memcpy( &data, &the_data, sizeof(POD) );
}
POD value ( void ) const {
POD result;
put( result );
return ( result );
}
};
#include <fstream>
int main ( void ) {
io_converter<intic;
{
std::ofstream file ( "test.bin", std::ios::binary );
for ( int i = 0; i < 1000; ++i ) {
ic.get( i );
file << ic;
}
}
{
std::ifstream file ( "test.bin", std::ios::binary );
while ( file >ic ) {
std::cout << ic.value() << '\n';
}
}
}
Of course, this is inefficient in that it copies the data in memory around
without a purpose. So alternatively, you may also want to ponder about
this:
#include <cstring>
#include <iostream>
#include <cstddef>
template < typename POD >
class binary_wrapper {
POD & the_data;
friend
std::ostream & operator<< ( std::ostream & o_str,
binary_wrapper const & ic ) {
o_str.write( static_cast<char*>( static_cast<void*>( &ic.the_data ) ),
sizeof(POD) );
return ( o_str );
}
friend
std::istream & operator>( std::istream & i_str,
binary_wrapper & ic ) {
i_str.read( static_cast<char*>( static_cast<void*>( &ic.the_data ) ),
sizeof(POD) );
return ( i_str );
}
public:
binary_wrapper ( POD & data )
: the_data ( data )
{}
POD & value ( void ) {
return ( the_data );
}
POD const & value ( void ) const {
return ( the_data );
}
};
#include <fstream>
int main ( void ) {
{
std::ofstream file ( "test.bin", std::ios::binary );
int i = 0;
binary_wrapper<intbw ( i );
for ( ; i < 1000; ++i ) {
file << bw;
}
}
{
int i;
binary_wrapper<intbw ( i );
std::ifstream file ( "test.bin", std::ios::binary );
while ( file >bw ) {
std::cout << i << '\n';
}
}
}
BTW: you really shouldn't be doing this.
Best
Kai-Uwe Bux