w+ не работает при попытке прочитать содержимое файла

Код:

#include <stdio.h>

void main() {
    FILE *ptr;
    char buff[255];
    ptr = fopen("Test.txt", "w+");

    if (ptr != NULL) {
        printf("Success\n");
    }

    fputs("Hello", ptr);

    fgets(buff, 255, (FILE *)ptr);
    printf("%s", buff);
    fclose(ptr);
}

Файл "Text.txt" имеет содержимое "Hello", когда я его открыл, но я просто не могу распечатать его с fgets, Что я тут не так сделал?

3 ответа

Решение

В вашем коде несколько проблем:

  • Вы должны позвонить в fseek(), fsetpos() или же rewind() переключаться между записью и чтением из потока, и наоборот.

  • Прототип для main без аргументов int main(void),

  • Нет необходимости кастовать ptr в fgets(buff, 255, (FILE *)ptr);, Бесполезные приведения могут скрывать несоответствия типов и другие подобные ошибки.

  • Вы не проверяете возвращаемое значение fgets() перед прохождением buff в printf(), Это имеет неопределенное поведение, если fgets() терпит неудачу, это делает в вашем случае.

  • Вы проверяете возвращаемое значение fopen(), но все же передать потенциально нулевой ptr к другим функциям потока, вызывая неопределенное поведение.

Вот исправленная версия:

#include <stdio.h>

int main(void) {
    FILE *ptr;
    char buff[255];

    ptr = fopen("Test.txt", "w+");
    if (ptr == NULL) {
        printf("Cannot open Test.txt\n");
        return 1;
    }
    printf("Success\n");

    fputs("Hello", ptr);
    rewind(ptr);
    if (fgets(buff, sizeof buff, ptr)) {
        printf("%s", buff);
    } else {
        printf("Cannot read from stream\n");
    }
    fclose(ptr);
    return 0;
}

Вы не перематывали файл перед чтением. fseek(ptr, 0, SEEK_SET); или же rewind(ptr);

Прочитайте, например, https://en.cppreference.com/w/c/io/fopen

Смелый мной.

В режиме обновления ('+') могут выполняться как ввод, так и вывод, но за выводом не может следовать ввод без промежуточного вызова fflush, fseek, fsetpos или rewind, а за вводом не может следовать вывод без промежуточного вызова fseek, fsetpos или rewind, если операция ввода не встретила конец файла. В режиме обновления реализациям разрешено использовать двоичный режим, даже если указан текстовый режим.

Другие вопросы по тегам