Нужна помощь в выяснении, в чем проблема с fgets - PullRequest
2 голосов
/ 06 мая 2019

Итак, в основном у меня есть указатель на файл, содержащий 80 цифр от 0 до 1, и мне нужно поместить их в строку, чтобы потом что-то с ней сделать.

Функция возвращает NULL, и я не могу найти, что не так, потому что, если он возвращает NULL, это просто означает ошибку.

    FILE *fpr = fopen(path, "r");
    FILE *fpw = fopen("code.txt", "w");
    char *str = calloc(81, sizeof(char));
    if (fpr == NULL || fpw == NULL) {
        printf("yikes");
    }
    if (fgets(str, 80, fpr) != NULL) { //HERE ITS NULL
        int p1 = 0;
        int p2 = 0;

Я действительно все продумал, и я либо действительно тупой, либо очевидной проблемы нет.

1 Ответ

3 голосов
/ 06 мая 2019

В фрагменте кода есть несколько проблем:

  • если какой-либо из файлов не может быть открыт, вы все равно вызываете fgets(), что ведет к неопределенному поведению, если fpr равно NULL. Сделайте отдельный тест для каждого FILE*, напечатайте более явное сообщение об ошибке и выйдите из программы.
  • Вы должны передать размер массива fgets(), 81 вместо 80.
  • массив должен быть выделен не менее чем на 82 байта: 80 символов плюс завершающий символ новой строки и терминатор нулевого байта.
  • вы не проверяете наличие ошибки выделения памяти. Вы даже не должны выделять память, локальный массив в порядке для небольшого размера, например 82 байта.

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

#include <errno.h>
#include <stdio.h>

    ...
    char str[82];
    FILE *fpr = fopen(path, "r");
    if (fpr == NULL) {
        fprintf(stderr, "cannot open input file %s: %s\n", path, strerror(errno));
        exit(1);
    }
    FILE *fpw = fopen("code.txt", "w");
    if (fpw == NULL) {
        fprintf(stderr, "cannot open output file %s: %s\n", "code.txt", strerror(errno));
        exit(1);
    }
    if (fgets(str, sizeof str, fpr)) {
        int p1 = 0;
        int p2 = 0;
        ...

Всегда проверяйте условия ошибок и печатайте явные сообщения об ошибках, вы сэкономите бесчисленные часы отладки.

...