Напишіть функцію, не використовуючи значення шуканого значення

Я намагаюся використовувати C ++, щоб написати запис у певному місці у файлі

так в основному у мене є

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

Але незалежно від того, що я роблю це, завжди пишу в кінці файлу.

Я думаю, це пов'язано з iso :: app , оскільки відповідно до документації

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

Але якщо я використовую їв , ніщо не завжди стирає вміст файлу.

Будь-яка допомога буде чудово :)

4

3 Відповіді

Так, це iOS :: app , що викликає цю поведінку. Замініть його на iOS :: 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.

5
додано
@ Пат: Ну, за замовчуванням це не має значення, оскільки ви не використовуєте його (ви використовуєте iOS :: binary ... ). Крім того, коли ви кажете "перерви", яким чином саме?
додано Автор NPE, джерело
Потік за умовчанням - для iOS :: out. Додавання iOS :: in розбиває програму.
додано Автор Paté, джерело
Ви перевірили прапорці помилки (eofbit, failbit, badbit)?
додано Автор Dana Holt, джерело
@ Paté: Так, ви не можете шукати потім вставити дані. Він просто почне перезапис існуючих даних. Ви повинні вивести першу частину (до того, де ви хочете вставити її), вставити нові дані, а потім додати інші.
додано Автор Dana Holt, джерело

Режим додавання файлу

Якщо ОС (і мережева файлова система, якщо застосовується) підтримує режим addpend, режим налаштування додавання гарантує, що записані дані не перезаписують існуючі дані у файлі, коли є декілька авторів. Це те, чого ви не можете обійтися без додавання режиму, через гонки між пошуком та написанням різних процесів. Це важлива гарантія для файлів журналів.

У режимі додавання ви можете писати лише наприкінці файлу за визначенням.

Iostream відкриті режими

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

Відповідно до таблиці «Файли відкритих режимів» в [filebuf.members], поведінка filebuf :: open визначається в термінах відкритих режимів fopen :

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

Відповідно до fopen man , режими означають:

  • 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.

Нарешті, ate означає fseek (файл, 0, SEEK_END) .

Отже, якщо ви хочете відкрити для написання у довільній позиції, не руйнуючи існуючі дані, вам потрібно fopen (s, r +) або ofstream (s, iOS :: in | iOS :: out) .

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

POSIX світі

Замість цього ви можете скористатись функцією POSIX open для прямого доступу до відкритих прапорів POSIX: O_READ , O_WRITE , O_CREAT O_EXCL , O_TRUNC ... Вони не набагато потужніші, але також незалежні та добре поводяться, на відміну від filebuf :: open код> прапори

Звичайно, ця функція не є частиною стандартної C ++. Я вважаю, що всі відповідні системи підтримують open .

1
додано

Ви намагалися використовувати iOS :: out замість iOS :: app ?

EDIT:

Після прочитання документів, на які посилається @curiousguy, вам буде потрібно iOS :: in | iOS :: out , а не просто iOS :: out , щоб не обрізати.

1
додано
Ви хочете скоротити існуючий файл?
додано Автор curiousguy, джерело
@ curiousguy: Ні, після прочитання документів я оновив мою відповідь.
додано Автор Dana Holt, джерело
IT KPI C/С++ новым годом
IT KPI C/С++ новым годом
747 учасників

Чат обсуждения С/С++. - Вопросы "напишите за меня лабу" - это оффтоп. - Оффтоп, флуд, оскорбления и вбросы здесь не приняты. - За нарушение - предупреждение или mute на неделю. - За спам и рекламу - ban. Все чаты IT KPI: https://t.me/itkpi/1147