Как правильно обрабатывать ошибки с помощью функции fopen - PullRequest
0 голосов
/ 27 сентября 2019

Я написал программу, которая просит пользователя ввести полный путь к файлу.Затем он попытается открыть этот файл из предоставленной строки имени пути.Я использовал стандартную проверку ошибок, рекомендованную большинством книг, которая заключается в закрытии программы, если fopen () возвращает NULL (что будет сделано в случае, если файл не существует).Когда я запускаю программу и при появлении запроса вводю несколько случайных символов (очевидно, недействительное имя файла), моя программа зависает с ошибкой во время выполнения, потому что она пытается открыть этот файл, который не существует.

Какой смысл в стандартной проверке ошибок (pfile == NULL), если ваша программа уже потерпела крах при вызове fopen ()?Смотрите ниже код.

Я использую LabWindows CVI 2017 в качестве среды, в которой используется компилятор clang.Смотрите изображение ошибки времени выполнения.

enter image description here

#include <stdio.h>
#include <string.h>

#define MAX 200

int main (void){

    char buffer[MAX];
    int len = 0;
    FILE *pfile = NULL;

    printf("please enter the full pathname of the file you wish to process.\n");

    fgets(buffer, MAX, stdin);

    len = strlen(buffer);

    buffer[len - 1] = '\0';

    pfile = fopen(buffer, "r");

    if(pfile == NULL){
        printf("not a valid filename, press any key to exit.");
        getchar();
        return -1;
    }

    int sum = 0;
    int c = 0;

    while((c = fgetc(pfile)) != EOF){
        sum += sizeof(c);
    }

    printf("the size of your file is %d\n", sum);

    getchar();

    return 0;
}

Ответы [ 2 ]

1 голос
/ 28 сентября 2019

Обычные правила проверки ошибок в подобных ситуациях:

  1. Проверять наличие ошибок.(Вы делаете это.)
  2. Распечатайте полезное сообщение об ошибке.(Вы делаете это.)
  3. Вывести сообщения об ошибках на stderr.
  4. Если ошибка связана с файлом, включите имя файла в сообщение об ошибке.
  5. Если ошибка связана с функцией, которая устанавливает errno, распечатайте текст «perror» («Нет такого файла или каталога» и т. Д.).
  6. Если вы пишете инструмент, который будет комбинироватьсяв более крупные сценарии включите имя программы в сообщение об ошибке.
  7. Если ошибка возникает из-за читаемого вами входного файла, распечатайте имя этого файла и номер строки.

Принимая правила с 1 по 6, улучшенная версия вашей проверки ошибок будет

if(pfile == NULL) {
    fprintf(stderr, "%s: can't open %s: %s\n", progname, buffer, strerror(errno));
    return EXIT_FAILURE;
}

. Для этого вам понадобится:

#include <string.h>
#include <errno.h>

Еслиэто слишком много работы, более простой способ - просто позвонить

perror(buffer);

, хотя это несколько падает по правилам 2, 6 и 7.

1 голос
/ 28 сентября 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...