You are not paying attention to the file opening modes in the constructor call std::ofstream
and in the reference position passed as parameter to the method std::ofstream::seekp()
.
Follows a function capable of writing a "generic" structure into 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 binary test file called saida.bin
containing 5
records:
#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 capable of changing only the Quarto
record 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;
}
Filing cabinet modified 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.@..
What have you tried? It’s a good step for us to understand precisely where your doubt is. In fact, it would just avoid opening the file as written only, maybe what you want is the way to
append
orread+
, which also allows writing– Jefferson Quesado
the ideal is to edit the question, then at most mark me in the comment for me to see the update.
– Jefferson Quesado
@Jeffersonquesado
– Raphael Roriz
Possible duplicate of Overwriting records in binary file
– user28595
@Articuno , really ,forgot to delete the other question , thank you
– Raphael Roriz
@Raphaelroriz keep erasing issues is bad, very bad. Better try to save than create new copies, and the other issue had salvation. Gets the hint
– Jefferson Quesado
@Jeffersonquesado thanks for the tip!
– Raphael Roriz