[PC] Obsługa błędu otwarcia pliku w programie konsolowym.

W tym miejscu zadajemy pytania na temat języka C, dzielimy się swoją wiedzą, udzielamy wsparcia, rozwiązujemy problemy programistyczne.
Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

[PC] Obsługa błędu otwarcia pliku w programie konsolowym.

Postautor: Antystatyczny » sobota 11 cze 2016, 15:12

Witam serdecznie.

Dłubię dzisiaj trochę przy programie konsolowym ucząc się przy okazji pracy na plikach. Napotkałem na dość uciążliwy problem "wywalania się" programu w chwili, gdy podawałem nieprawidłową nazwę pliku jako parametr wywołania. na szczęście z pomocą przyszło MSDN i szybciutko opracowałem prostą obsługę błędu. Tak to wygląda:

Kod: Zaznacz cały

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>


#define PRG_NAME         0
#define SRC_FILE         1
#define DST_FILE         2

int main(int argc, char * argv[])
{
   FILE *src; /* Uchwyt na otawrty plik. */
   errno_t err; /* Zmienna przechowująca rezultat próby otwarcia pliku. */

   /* Zerujemy globalna zmienną przechowującą kody błędów programu. */
   _set_errno(0);

   /* Próbujemy otworzyć plik o nazwie przekazanej przez ścieżkę wywołania programu. */
   err = fopen_s(&src, argv[SRC_FILE], "r");

   /* Jeśli podczas próby otwarcia wystąpił jakikolwiek błąd... */
   if (err != 0)
   {
      /* Drukujemy w konsoli tenże błąd... */
      perror("Oh no!");

      /*...a następnie kasujemy błąd, by system operacyjny nie zaczął marudzić. */
      _set_errno(0);

      /* A to tylko taki dodatkowy wodotrysk. */
      printf("Program terminated\r\n");

      /* Błąd obsłużyliśmy i możemy wyjść z programu bez informacji o błędzie.
       (Chyba, że ktoś koniecznie potrzebuje zwrócić numer błędu, to dlaczego by nie...) */
      return EXIT_SUCCESS;
   }

   /* Otwarcie pliku powiodło się, o czym informujemy użytkownika. */
   printf("File opened successfully!\r\n");
   
   /* Koniec programu. */
   return EXIT_SUCCESS;
}


Być może zamiast zmiennej err można by wykorzystać _get_errno(), ale póki co powyższa wersja działa bardzo dobrze. Gdyby jednak ktoś miał ciekawszy/lepszy sposób, to chętnie się z nim zapoznam.

Pozdrawiam!
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: [PC] Obsługa błędu otwarcia pliku w programie konsolowym.

Postautor: Antystatyczny » sobota 11 cze 2016, 16:41

Ha! Okazuje się, że przedstawiona w poprzednim poście obsługa błędów nie działa, gdy nie przekażemy żadnej nazwy pliku poprzez ścieżkę wywołania programu i program się wywala, ale... Tutaj sprawa jest prosta. Wystarczy sprawdzić, czy wskaźnik na nazwę pliku (w tym przypadku argv[SRC_FILE]) jest różny od NULL. Jeśli jednak napotykamy NULL, po prostu nie próbujemy otworzyć pliku, bo to przecież byłoby bez sensu, prawda? Oto zmodyfikowana wersja programu:

Kod: Zaznacz cały

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

#define PRG_NAME         0
#define SRC_FILE         1
#define DST_FILE         2

int main(int argc, char * argv[])
{
   FILE *src; /* Uchwyt na otwarty plik. */
   errno_t err; /* Zmienna przechowująca rezultat próby otwarcia pliku. */

   /* Sprawdzamy, czy przekazano jakąkolwiek nazwę pliku w ścieżce wywołania programu. */
   if (argv[SRC_FILE] == NULL)
   {
      /* Jednak nie przekazałem nazwy pliku. Drukuję informację i kończę program. */
      printf("Missing source file name. Program terminated.\r\n");

      return EXIT_SUCCESS;
   }

   /* Zerujemy globalną zmienną przechowującą kody błędów programu. */
   _set_errno(0);

   /* Próbujemy otworzyć plik o nazwie przekazanej przez ścieżkę wywołania programu. */
   err = fopen_s(&src, argv[SRC_FILE], "r");

   /* Jeśli podczas próby otwarcia wystąpił jakikolwiek błąd... */
   if (err != 0)
   {
      /* ...drukujemy w konsoli tenże błąd... */
      perror("Oh no!");

      /* ...a następnie kasujemy błąd, by system operacyjny nie zaczął marudzić. */
      _set_errno(0);

      /* A to tylko taki dodatkowy wodotrysk. */
      printf("Program terminated\r\n");

      /* Błąd obsłużyliśmy i możemy wyjść z programu bez informacji o błędzie.
       (Chyba, że ktoś koniecznie potrzebuje zwrócić numer błędu, to dlaczego by nie...) */
      return EXIT_SUCCESS;
   }

   /* Otwarcie pliku powiodło się, o czym informujemy użytkownika. */
   printf("File opened successfully!\r\n");
   
   /* Koniec programu. */
   return EXIT_SUCCESS;
}
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.


Wróć do „Pisanie programów w C”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 3 gości