Write function does not use seekp value

I am trying to use C ++ to write a record in a specific place in a file

so I

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 is always written at the end of the file.

I believe this is related to iso::app , because according to the documentation

 app (append) Set the stream position indicator to the end of the stream before each output operation 

But if I use ate or nothing, it always deletes the contents of the file.

Any help would be great :)

+4
source share
3 answers

Yes, this is ios::app causing this behavior. Replace it with ios::in | ios::out ios::in | ios::out .

edit: It is unclear from your question, but your comments suggest that you are trying to insert data in the middle of the file, rather than overwriting part of the file. If this is true, you should pretty much use a second file for this.

+5
source

File add mode

If the OS (and the network file system, if applicable) supports the add mode, setting the add mode ensures that the recorded data will not overwrite existing data in the file if there are multiple writers. This is something you cannot do without the add mode, because of the race between searching and recording from different processes. This is an important guarantee for log files.

In add mode, you can write only at the end of the file by definition.

Iostream open modes

According to [ofstream.cons], ofstream (s, mode) calls rdbuf()->open(s, mode|ios_base::out) .

According to the table โ€œFile open modesโ€ in [filebuf.members], the behavior of filebuf::open is defined in fopen open modes:

  • out means "W"
  • app and app|out mean "a"
  • in|out means "r +"
  • in|out|trunc means "w +"

According to fopen man , modes mean:

  • r + Open for reading and writing.
  • w Trim the file to zero length or create a text file for writing.
  • w + Open for reading and writing. A file is created if it does not exist, otherwise it is truncated.
  • a Open for adding (entry at the end of the file). A file is created if it does not exist.

In the end, ate means fseek(file,0,SEEK_END) .

So, if you want to open for recording in an arbitrary position without destroying the existing data, you need fopen(s,"r+") or ofstream (s, ios::in|ios::out) .

So, in C / C ++, you also need read access to the file to open it for writing without overwriting!

POSIX World

Instead, you can use the open POSIX function 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 behave well. Unlike filebuf::open flags.

Of course, this function is not part of the C ++ standard. I believe that all systems related to normal programming (not specialized markets with a special feature) support open .

+2
source

Have you tried using ios::out instead of ios::app ?

EDIT:

After reading the documents referenced by @curiousguy, you need ios::in | ios::out ios::in | ios::out instead of ios::out to avoid truncation.

+1
source

All Articles