Запіс функцыя не выкарыстоўваецца seekp значэння

Я спрабую выкарыстоўваць C ++, каб зрабіць запіс у пэўным месцы ў файле

таму растлумачу ў мяне ёсць

ofstream ofs("file.dat", ios::binary | ios::app);
ofs.seekp(220, ios::beg);
ofs.write((char *)&i, sizeof(i));

Але незалежна ад таго, што я раблю гэта заўсёды пісаць у канцы файла.

Я мяркую, што гэта звязана з ISO :: прыкладання , таму што ў адпаведнасці з дакументацыяй

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

Але калі я выкарыстоўваю <моцны> еў ці нічога ён заўсёды сцірае змесціва файла.

Любая дапамога будзе выдатна :)

4

3 адказы

Так, гэта ІАА-:: прыкладанне , што выклікае такія паводзіны. Заменіце яго КСН :: ў | ІАА-:: з .

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.

5
дададзена
@ Паштэт: Ну, па змаўчанні не мае ніякага значэння, так як вы не выкарыстоўваеце (вы карыстаецеся ІАА-:: Binary ... ). Акрамя таго, калі вы кажаце, «парывы», дык што ж тады менавіта?
дададзена аўтар NPE, крыніца
ofstream па змаўчанні з'яўляецца iOS :: з іх. Даданне ІАА-:: у перапынках праграмы.
дададзена аўтар Paté, крыніца
Вы праверылі сцягі памылак (eofbit, failbit, badbit)?
дададзена аўтар Dana Holt, крыніца
@ Паштэт: Так, вы не можаце шукаць затым ўставіць дадзеныя. Гэта будзе проста пачаць перазапіс існых дадзеных. Вы павінны вывесці першую частку (да таго часу, дзе вы хочаце ўставіць), устаўце новыя дадзеныя, а затым дадаць астатнія.
дададзена аўтар Dana Holt, крыніца

рэжым дадання файла

Калі АС (і сеткавай файлавай сістэмы, калі гэта дастасавальна) падтрымлівае рэжым дадання, налады дадання рэжыму гарантуе, што дадзеныя, запісаныя не перазапісваць існуючыя дадзеныя у файле, калі Ёсць некалькі пісьменнікаў. Гэта тое, што вы не можаце абысціся без рэжыму нясьпешнага дапісваньня ўсялякай, з-за гонкі паміж шукаць і пісаць ад розных працэсаў. Гэта важная гарантыя для лог-файлаў.

У рэжыме дадання, можна пісаць толькі ў канцы файла па азначэнні.

Iostream адкрытых рэжымаў

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

У адпаведнасці з табліцай «Файл адкрытых рэжымаў» у [filebuf.members], паводзіны filebuf :: адкрытага вызначана ў тэрміне Еореп адкрытых рэжымы:

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

Згодна з FOPEN чалавек , рэжымы азначаюць:

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

Нарэшце, еў азначае FSEEK (файл, 0, SEEK_END) .

Такім чынам, калі вы хочаце адкрыць для запісу ў адвольным становішчы, без разбурэння існуючых дадзеных, вам трэба FOPEN (ы, «г +») або ofstream (s, iOS :: ў | ІАА- :: з) .

IOW, ў C/C ++ вы таксама павінны прачытаць доступ да файла, каб адкрыць яго для запісу, ня перапісваючы яго!

POSIX свет

Вы можаце выкарыстоўваць POSIX Адкрыць <код /> функцыю замест таго, каб атрымаць прамы доступ да адкрытых сцягі POSIX: O_READ , O_WRITE , O_CREAT , O_EXCL , O_TRUNC ... Яны не з'яўляюцца значна больш магутным, але і незалежнымі і добра сябе, у адрозненне ад filebuf :: адкрыты сцягі.

Вядома, гэтая функцыя не з'яўляецца часткай стандарту C ++. Я лічу, што ўсю неабходную падтрымку сістэмы адкрыйце .

1
дададзена

Вы спрабавалі выкарыстаць ІАА-:: з замест ІАА-:: прыкладанне ?

EDIT:

Пасля прачытання дакументацыі, што @curiousguy спасылкі гэта выглядае, як вам трэба будзе :: ИСН ў | ІАА-:: з , а не толькі iOS :: з , каб ўсячэнне.

1
дададзена
Вы хочаце пакараціць існуючы файл?
дададзена аўтар curiousguy, крыніца
@curiousguy: Не, пасля чытання дакументацыі я абнавіў свой адказ.
дададзена аўтар Dana Holt, крыніца