You are not minding the file opening modes in the std::ofstream
constructor call and in the reference position passed as a parameter to the std::ofstream::seekp()
method.
Here is a function that can write a "generic" structure to a binary file:
void gravar_arquivo( void * p, std::size_t n, const char * arq, long pos = -1 )
{
if( pos == -1 )
{
// Apenas inclui um novo registro no final do arquivo (append)
std::ofstream ofs( arq, std::ios::binary | std::ios::out | std::ios::app );
ofs.write( (char*) p, n );
ofs.close();
}
else
{
// Grava em uma posicao especifica do arquivo
std::ofstream ofs( arq, std::ios::binary| std::ios::out | std::ios::in );
ofs.seekp( n * pos, std::ios::beg );
ofs.write( (char*) p, n );
ofs.close();
}
}
Program for generating a test binary file named saida.bin
containing 5
registrations:
#include <fstream>
#include <cstring>
typedef struct foobar_s
{
char id;
char text[16];
} foobar_t;
void gravar_arquivo( void * p, std::size_t n, const char * arq, long pos = -1 )
{
if( pos == -1 )
{
// Apenas inclui um novo registro no final do arquivo (append)
std::ofstream ofs( arq, std::ios::binary | std::ios::out | std::ios::app );
ofs.write( (char*) p, n );
ofs.close();
}
else
{
// Grava em uma posicao especifica do arquivo
std::ofstream ofs( arq, std::ios::binary| std::ios::out | std::ios::in );
ofs.seekp( n * pos, std::ios::beg );
ofs.write( (char*) p, n );
ofs.close();
}
}
int main( void )
{
foobar_t fb[5];
/* Preenche 5 registros */
fb[0].id = 1; std::strcpy( fb[0].text, "Alpha" );
fb[1].id = 2; std::strcpy( fb[1].text, "Beta" );
fb[2].id = 3; std::strcpy( fb[2].text, "Gamma" );
fb[3].id = 4; std::strcpy( fb[3].text, "Delta" );
fb[4].id = 5; std::strcpy( fb[4].text, "Episilon" );
/* Grava sequenciamente os 5 registro em arquivo binario */
for( int i = 0; i < 5; i++ )
gravar_arquivo( (void*) &fb[i], sizeof(foobar_t), "saida.bin" );
return 0;
}
Generated file saida.bin
:
0000000: 0141 6c70 6861 0000 2699 33af 4d7f 0000 .Alpha..&.3.M...
0000010: 0102 4265 7461 0000 0000 0000 0000 0000 ..Beta..........
0000020: 0100 0347 616d 6d61 0018 75ae 4d7f 0000 ...Gamma..u.M...
0000030: 0100 0004 4465 6c74 6100 4000 0000 0000 ....Delta.@.....
0000040: 0000 0000 0545 7069 7369 6c6f 6e00 0000 .....Episilon...
0000050: 700b 4000 00 p.@..
Now, a program that can only change the Quarto
log contained in the file saida.bin
:
#include <fstream>
#include <cstring>
typedef struct foobar_s
{
char id;
char text[16];
} foobar_t;
void gravar_arquivo( void * p, std::size_t n, const char * arq, long pos = -1 )
{
if( pos == -1 )
{
// Apenas inclui um novo registro no final do arquivo (append)
std::ofstream ofs( arq, std::ios::binary | std::ios::out | std::ios::app );
ofs.write( (char*) p, n );
ofs.close();
}
else
{
// Grava em uma posicao especifica do arquivo
std::ofstream ofs( arq, std::ios::binary| std::ios::out | std::ios::in );
ofs.seekp( n * pos, std::ios::beg );
ofs.write( (char*) p, n );
ofs.close();
}
}
int main( void )
{
foobar_t fb;
fb.id = 99;
std::strcpy( fb.text, "Omega" );
gravar_arquivo( (void*) &fb, sizeof(foobar_t), "saida.bin", 3 );
return 0;
}
modified file saida.bin
:
0000000: 0141 6c70 6861 0000 2699 33af 4d7f 0000 .Alpha..&.3.M...
0000010: 0102 4265 7461 0000 0000 0000 0000 0000 ..Beta..........
0000020: 0100 0347 616d 6d61 0018 75ae 4d7f 0000 ...Gamma..u.M...
0000030: 0100 0063 4f6d 6567 6100 0000 0840 0000 ...cOmega....@..
0000040: 0000 00c0 0545 7069 7369 6c6f 6e00 0000 .....Episilon...
0000050: 700b 4000 00 p.@..