18.22 Fehlerausgabe mit strerror und perror
 
Wenn bei einem Systemaufruf ein Fehler auftritt, bekommt die globale Variable errno einen entsprechenden Fehlerwert gesetzt. Mit den beiden Funktionen strerror() und perror() können Sie diese Systemfehlermeldung ausgeben lassen. Die Variable errno ist in der Headerdatei <errno.h> wie folgt deklariert:
extern int errno;
Ebenfalls in dieser Headerdatei <errno.h> sind die Konstanten (Fehlernummern) deklariert, die die Variable errno annehmen kann. Jede dieser Konstanten beginnt mit dem Buchstaben »E«. Diese Fehlernummern sind allerdings, abgesehen von zwei Konstanten, System- und Compiler-abhängig. Folgende zwei Konstanten sind auf allen Systemen gleich:
Tabelle 18.9
Fehlerbehandlungs-Konstanten für mathematische Funktionen
Konstante
|
Bedeutung
|
EDOM
|
Unzulässiges Argument für eine mathematische Funktion
|
ERANGE
|
Ergebnis außerhalb des darstellbaren Bereichs
|
Weitere – allerdings wie schon erwähnt, System- und Compiler-abhängige – Konstanten und ihre Bedeutungen sind:
Tabelle 18.10
Fehlerbehandlungs-Konstanten bei Systemaufrufen
Fehlercode
|
Bedeutung
|
EZERO
|
Fehler 0
|
EINVFNC
|
Ungültige Funktionsnummer
|
ENOFILE
|
Datei nicht gefunden
|
ENOPATH
|
Pfad nicht gefunden
|
ECONTR
|
Speicherblöcke zerstört
|
EINVMEM
|
Ungültige Speicherblockadresse
|
EINVENV
|
Ungültiges Environment
|
EINVFMT
|
Ungültiges Format
|
EINVACC
|
Ungültiger Zugriffscode
|
EINVDAT
|
Ungültige Daten
|
EINVDRV
|
Ungültige Laufwerksangabe
|
ECURDIR
|
Versuch, das aktuelle Verzeichnis zu löschen
|
ENOTSAM
|
Nicht das gleiche Gerät
|
ENMFILE
|
Keine weiteren Dateien mehr
|
ENOENT
|
Datei oder Verzeichnis existiert nicht
|
EMFILE
|
Zu viele geöffnete Dateien
|
EACCES
|
Zugriff verweigert
|
EBADF
|
Ungültiger Datei-Deskriptor
|
ENOMEM
|
Zu wenig Speicher
|
ENODEV
|
Gerät existiert nicht
|
EINVAL
|
Ungültiges Argument
|
E2BIG
|
Argumentliste ist zu lang
|
ENOEXEC
|
Fehler beim Exec-Format
|
EXDEV
|
Kreuzverbindung von Geräten
|
EFAULT
|
Unbekannter Fehler
|
EEXIST
|
Datei existiert bereits
|
Dies dürften jetzt nicht alle gewesen sein bzw. auf anderen Systemen wieder zu viele. Sie sollten in der Headerdatei <errno.h> oder unter Linux auf der man-Page »intro« nachsehen.
Die Variable errno wird bei Programmstart normalerweise auf 0 gesetzt, da es keine Fehlernummer mit dem Wert 0 gibt. Deshalb sollte errno jedes Mal, wenn eine Systemfunktion aufgerufen wird, wieder auf 0 gesetzt werden.
Im ersten Beispiel wird die Funktion perror() verwendet. Zuerst die Syntax zu dieser Funktion:
#include <stdio.h>
void perror(const char *meldung);
Wenn für meldung kein NULL-Zeiger angegeben wurde, wird der String meldung mit anschließendem Doppelpunkt, gefolgt von einer zur errno gehörenden Fehlermeldung, ausgegeben (mit abschließendem '\n'). Rufen Sie hingegen diese Funktion mit dem NULL-Zeiger auf, wird nur eine zur errno gehörende Fehlermeldung ausgegeben. Geschrieben wird diese Fehlermeldung auf die Standardfehlerausgabe (stderr).
/* perror.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *fp;
fp = fopen("keinedatei.dat", "r");
if (NULL == fp) {
perror("Kann nicht aus Datei lesen ");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Das Programm versucht, die Datei »keinedatei.dat« zu öffnen. Falls diese nicht existiert, wird eine entsprechende Fehlermeldung ausgegeben:
Kann nicht aus Datei lesen : No such file or directory
Der Funktion perror() kann auch ein NULL-Zeiger übergeben werden:
perror(NULL);
In diesem Fall würde nur das Folgende ausgegeben:
No such file or directory (ENOENT)
Das Gleiche soll jetzt auch mit der Funktion strerror() realisiert werden. Die Syntax der Funktion:
#include <string.h>
char *strerror(int error_nr);
Die Funktion liefert als Rückgabewert einen Zeiger auf einen String, welcher zur Systemfehlermeldung der Variablen errno passt. Der Parameter error_nr beinhaltet in der Regel die Fehlervariable von errno.
/* strerror.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main(void) {
FILE *fp;
fp = fopen("keinedatei.dat", "r");
if (NULL == fp) {
fprintf(stderr, "%s\n", strerror(errno));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Das Programm läuft genauso ab wie das Programm zuvor mit perror().
Mit dem nun folgenden Programm wird eine Datei mit dem Namen »testfile« erstellt. Zuerst soll die Datei zum Lesen geöffnet werden. Anschließend wird überprüft
if(errno == ENOENT)
ob die Variable errno den Wert der Konstante ENOENT hat. Wenn ja, bedeutet dies, dass keine solche Datei existiert, und sie soll somit neu angelegt werden. Sollte es Probleme beim Anlegen dieser Datei geben, so wird dies mit dem nächsten perror()-Aufruf ausgegeben.
/* isfile.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define ESUCCESS 0
int main(void) {
FILE *fp;
fp = fopen("testfile", "r");
if(errno == ENOENT) {
/* errno wieder zurücksetzen */
errno = ESUCCESS;
fp = fopen ("testfile", "w");
if(NULL == fp) {
perror(NULL);
return EXIT_FAILURE;
}
else
printf("Datei \"testfile\" angelegt\n");
}
else
printf("Datei \"testfile\" exisitiert bereits\n");
fclose(fp);
return EXIT_SUCCESS;
}
|