I'm trying to use C++ to write an entry in a specific place in a file
so basicly I have
ofstream ofs("file.dat", ios::binary | ios::app);
ofs.seekp(220, ios::beg);
ofs.write((char *)&i, sizeof(i));
But no matter what I do it always write at the end of the file.
I suppose this is related to iso::app
because according to the documentation
app (append) Set the stream's position indicator to the end of the stream before each output operation
But if I use ate or nothing it always erases the content of the file.
Any help would be great :)
Yes, it's the
ios::app
that's causing this behaviour. Replace it withios::in | ios::out
.edit: It wasn't clear from your question, but your comments suggest that you're trying to insert data in the middle of the file, rather than overwrite a portion of the file. If that is indeed the case, you pretty much have to use a second file for that.
Have you tried using
ios::out
instead ofios::app
?EDIT:
After reading the docs that @curiousguy referenced it looks like you would need
ios::in | ios::out
instead of justios::out
to keep from truncating.File append mode
If the OS (and network file system, if applicable) supports append mode, setting append mode guarantees that data written does not overwrite existing data in the file when there are multiple writers. That's something you cannot do without append mode, because of the race between seek and write from different processes. It is an important guarantee for log files.
In append mode, you can only write at end of file by definition.
Iostream open modes
According to [ofstream.cons],
ofstream (s, mode)
callsrdbuf()->open(s, mode|ios_base::out)
.According to the table "File open modes" in [filebuf.members], the behaviour of
filebuf::open
is defined in term offopen
open modes:out
means "w"app
andapp|out
mean "a"in|out
means "r+"in|out|trunc
means "w+"According to
fopen man
, the modes mean:Finally,
ate
meansfseek(file,0,SEEK_END)
.So, if you want to open for writing at arbitrary position, without destroying the existing data, you need
fopen(s,"r+")
orofstream (s, ios::in|ios::out)
.IOW, in C/C++ you also need read access to a file to open it for writing without overwriting it!
POSIX world
You may want to use the POSIX
open
function instead, in order to directly access the POSIX open flags:O_READ
,O_WRITE
,O_CREAT
,O_EXCL
,O_TRUNC
... They are not only much more powerful, but also independent orthogonal flags and well-behaved, unlikefilebuf::open
flags.Of course, this function is not part of standard C++. I believe all systems relevant for normal programming (not niche markets with special characteristics) support
open
.