17. Grundlagen der Fehlerbehandlung - fbi.h

Werbung
17. Grundlagen der Fehlerbehandlung
Fehlersituationen
Nenner im Bruch ist 0 / Division durch 0
Datei nicht vorhanden
Unzulässige Eingabe von Daten (z.B. Zeichen statt Zahl)
Adressierungsfehler (Pointer/Arrays)
Nicht existierendes Zeichen im string (z.B. str.at(12) für str=“text“)
Speicher reicht nicht (z.B. für Array)
Falsche Eingabe durch Benutzer
Konsequenz:
falsche Ergebnisse oder Programmabsturz
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
2
Fehlerbehandlung/Techniken
Bisher verwendete Techniken:
„konventionelle Methode“
Plausibilitätskontrolle von (Eingabe-)Daten/Ergebnissen -> return x
Definiertet Abbruch
Assert-Befehl
Neu
Exception-Handling
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
3
17.1 Konventionelle Methode
Man überprüft mittels
eines if-Befehls
einer passend geschriebenen Funktion
ob ein Fehler vorliegt.
Danach wird
dies der „anfordernden Funktion“ mitgeteilt mittels
eines returncodes (z.B. -1 für Fehler / 0 für OK )
eine Fehlermeldung am Bildschirm erzeugt und eine
Benutzereingabe angefordert
eine Fehlermeldung am Bildschirm erzeugt und das
Programm abgebrochen.
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
4
konventionelle Methode
Aufruf einer Funktion mit Rückgabewert vom Typ int
int ergebnis = funktion(.......);
if ( ergebnis==0 )
// alles OK
else
// dann wars ein Fehler
Durch unterschiedliche
Rückgabewerte kann man auch
unterschiedliche Fehlerarten
anzeigen.
Oder vom Typ bool
if ( funktion(.......) )
// alles OK
else
// dann wars ein Fehler
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
5
17.2 Assert-Befehl
Benötigt <assert.h>
assert ( boolscher Ausdruck)
Es soll sichergestellt werden, dass der boolsche Ausdruck true ist.
Falls der Ausdruck false ist, wird eine Systemfehlermeldung erzeugt und
das Programm beendet.
Beispiel:
Bruch::Bruch(string p_bezeichnung,int p_zaehler, int p_nenner) // Konstruktor
{
assert(p_nenner>0); // nenner muss > 0 sein
bezeichnung=p_bezeichnung;
zaehler=p_zaehler;
nenner=p_nenner;
//
};
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
6
Assert-Befehl/Aufruf
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
7
17.3 Exception-Handling
Grundidee
Trennung des normalen Programablaufs, der überwacht werden soll, von
dem Teil für die Fehlerbehandlung
Programmteil
unter
Überwachung
Meldung
(throw)
Programmteil
zur
Fehlerbehandlung
Meldung erfolgt durch die throw-Anweisung, welche ein sogenanntes
Fehlerobjekt in den Programmteil zur Fehlerbehandlung „wirft“. Das
Fehlerobjekt kann von beliebigem Typ sein also int, string, ein
Klassenobjekt usw.
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
8
Exception-Handling/Ablauf
1.
Kennzeichnung des Blocks, welcher Meldungen auslösen darf
try-Block
2. Anschliessend folgen ein oder mehrere Exception-Handler, welche die
„ausgeworfenen“ Fehlerobjekte in Empfang nehmen und abarbeiten.
Jeder Exception-Handler steht in einem
catch-Block
d.h. es folgen ein oder mehrere catch-Blöcke auf den try-Block;
3. Nach dem letzten catch-Block get es „ohne Exception-Handling“ weiter.
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
9
Exception-Handling/try-Block
try-Block
try
{
// hier stehen die Befehle, die Meldungen erzeugen dürfen
// mittels eines throw fehlerobjekt;
}
Beispiele für throw Anweisung:
throw “Fehler aufgetreten“; // Typ ist char*
throw i; // Typ ist int
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
10
Exception-Handling/catch-Block
catch-Block
catch (objekttyp name)
{
// hier wird festgelegt, was mit Fehlern, die ein Fehlerobjekt
// vom Typ objekttyp „werfen“, geschehen soll
}
Jeder catch-Block steht für einen Typ. Es kann mehrere catch-Blöcke
mit unterschiedlichen Typen geben.
Beispiel:
catch ( char* text)
{
cout <<text;
return 1;
}
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
11
Exception-Handling/catch-Block
Der Exeption-Handler
catch (...)
{
// Aktionen
}
reagiert auf alle anderen ausgeworfenen Fehlerobjekt-Typen, z.B. auf
solche, die von Systemmeldungen kommen.
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
12
Exception-Handling/Beispiel
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int i,z,n;
fstream out("ausgabe.txt",ios::out);
// try-Block
try
{
fstream ein;
ein.open("eingabe.txt",ios::in);
if ( ein.fail() )
throw "eingabe.txt kann nicht geoeffnet werden";
i=0;
ein >> i>>z>>n;
while (!ein.eof() )
{
i++;
if ( ein.fail() )
throw i;
//Verarbeitung
out<< i<<z;
ein >> i>>z>>n;
}
ein.close();
if ( ein.fail() )
throw "eingabe.txt kann nicht geschlossen werden";
// catch-Block
catch (char * str)
{
cout <<str<<endl;
return -1;
}
catch (int nr)
{
cout <<" Fehler in Zeile "<<nr<<endl;
return nr;
}
catch (...)
{
cout <<" unbekannter Fehler"<<endl;
}
// hier gehts weiter
cout << " das wars"<<endl;
return 0;
}
}
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
13
Exception-Handling/Beispiel
Wenn die Datei nicht da ist, wird das fail-Bit gesetzt.
Dies führt dann zum ersten throw – Typ char* .
Ist in der Datei beispielsweise ein Buchstabe wird das fail-Bit gesetzt.
Dies führt dann zum throw – Typ int.
Dr. Norbert Spangler / Grundlagen der Informatik
27.05.2007
14
Herunterladen