fstream seekg (), seekp () и write ()

Я ищу разъяснения о том, как seekg() а также seekp() работает относительно того, когда вы пишете в файл. Скажем, например, у меня был файл так:

offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10

Теперь я хочу открыть файл и сделать некоторые попытки чтения и записи значений.

fstream file;
file.open("file.txt", fstream::in |fstream::out | fstream::binary);
file.seekp(0, ios::end) // seek to the end of the file
int eofOffset = file.tellp(); // store the offset of the end-of-file, in this case 20

int key = 0;

file.seekg(12, ios::beg); // set the seek cursor to offset 12 from the beginning of the file
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 8
file.seekg(8, ios::beg); // set the seek cursor to offset 8 from the beginning of the file
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 6

Теперь я хочу написать в конец файла. Так как seekg() функция только перемещает курсор поиска, мой seekp() курсор все еще должен быть в конце файла, верно? Так:

int newKey = 12;
file.write((char *) &newKey, sizeof(int));

должен сделать мой файл похожим на:

offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10
offset 20: 12

Теперь, что произойдет с моим файлом, если я решу искать смещение и записать его значение как смещение к только что вставленному значению. Например, я хочу offset 8 держать eofOffset = 20 так как мы только что вставили 12 с этим смещением.

Если я сделаю:

file.seekp(8, ios::beg);
file.write((char *) &eofOffset, sizeof(int));

это правильно переписать мой файл, чтобы выглядеть так:

offset 0: 2
offset 4: 4
offset 8: 20
offset 12: 8
offset 16: 10
offset 20: 12

Пожалуйста, дайте мне знать, если я делаю какие-либо ошибки, используя seekg() а также seekp() функции.

21

Решение

Шаблон класса std::basic_filebuf содержит одну позицию файла

§ 27.9.1.1

  1. Класс basic_filebuf связывает оба ввода
    последовательность и последовательность вывода с файлом.
  2. Ограничения на чтение и запись последовательности, управляемой объектом класса basic_filebuf, такие же, как и для
    чтение и запись с помощью стандартных файлов библиотеки C.
  3. Особенно:
    • Если файл не открыт для чтения, последовательность ввода не может быть прочитана.
    • Если файл не открыт для записи, выходная последовательность не может быть записана.
    • Совместное положение файла поддерживается как для входной последовательности, так и для выходной последовательности.

Это означает, что когда вы используете std::basic_fstreamкоторый по умолчанию использует std::basic_filebuf, позиция одного файла перемещается обоими seekp() а также seekg(); если вы не используете отдельную переменную для хранения одной из позиций, чтобы затем вернуться к ней, вы не сможете отслеживать позиции и получить позиции независимо.

Смысл пункта 2 заключается в том, что между чтением и записью на fstream Вы должны либо очистить буфер, либо искать позицию файла при переходе от вывода к вводу, и вы должны либо находиться в конце файла, либо искать позицию файла при переходе от ввода к выводу.

Подробнее об этих ограничениях см. Раздел 7.19.5.3/7 стандарта C99 (« fopen функция «), или 7.21.5.3/7 из C11.

22

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]