Перемещает ли fseek() указатель файла в начало файла, если он был открыт в режиме "a + b"? - программирование

Перемещает ли fseek() указатель файла в начало файла, если он был открыт в режиме "a + b"?

Я хочу открыть файл, используя режим "a + b", т.е. если он не существует, он создается автоматически, но если это не так, я не хочу его перезаписывать. Я хочу иметь возможность читать и писать в файл.

Файл двоичный, и я хочу сохранить записи определенного struct в нем. Поэтому я хочу сделать fseek() в записи, которую хочу, а затем сохранить запись, используя fwrite().

Код выглядит следующим образом (MyRecord - это typedef до struct, а FILENAME - #define для имени файла):

int saveRecord(MyRecord *pRecord, int pos)
{
    FILE* file = fopen(FILENAME, "a+b");
    if (file == NULL)
    {
        printf("Unable to open file %s\n", FILENAME);
        return 0;
    }

    fseek(file, pos * sizeof(MyRecord), SEEK_SET);
    fwrite(pRecord, sizeof(MyRecord), 1, file);
    fclose(file);
    return 1;
}

Однако этот код просто добавляет запись в конец файла, даже если я установил pos в 0. Почему не работает fseek() с SEEK_SET в режиме добавления?

Я знаю, что могу просто открыть его с помощью "r + b", и если он не сможет открыть его с помощью "wb", но я хочу знать, почему это не работает и почему fseek() с SEEK_SET покидает указатель файла в конце. Любые ссылки на места, где это поведение документировано, оценены (потому что я не смог найти никого, или я использую неправильные ключевые слова).

4b9b3361

Ответ 1

Это потому, что в режиме a запись в FILE* всегда добавляется к концу. fseek только устанавливает указатель чтения в этом режиме. Это описано в стандарте C, 7.19.5.3 fopen:

Открытие файла с добавлением режима ('a' в качестве первого символа в аргументе режима) приводит к тому, что все последующие записи в файл будут принудительно перенесены в текущий текущий конец файла, независимо от входящих вызовов функции fseek.

Ответ 2

Используйте режим "r + b" и отключайтесь до "w + b", если он не работает.

Режим "a + b" позволяет читать и добавлять; "r + b" позволяет случайное чтение и запись.

Документация для fopen описывает, как файл ведет себя с разными режимами.

Ответ 3

Plain C не имеет разумного способа достижения желаемого. Если вы находитесь в системе POSIX или удаленно закрыты, вы можете использовать fd=open(FILENAME, O_CREAT|O_RDRW, 0666), а затем fdopen(fd, "rb+").

Изменить: Еще одна вещь, которую вы могли бы попробовать, с простым C:

f = fopen(FILENAME, "a+b");
if (!f) /* ... */
tmp = freopen(0, "r+b", f);
if (tmp) f = tmp;
else /* ... */