C++-Programmierung/ Brüche/ Ein- und Ausgabe

Aus Wikibooks
Zur Navigation springen Zur Suche springen


Als nächstes wollen wir dafür sorgen, dass unsere Brüche ebenso einfach ein- und ausgegeben werden können, wie die elementaren Datentypen. Sie wissen ja bereits, dass Sie hierfür nur den Ein- und Ausgabeoperator überladen müssen. Wir wollen die Brüche in der folgenden Form schreiben und lesen:

(Zähler/Nenner)

Die beiden folgenden Operatorfunktionen können Sie nach der Deklaration der Bruch-Klasse einfügen. Include-Dateien gehören natürlich an die übliche Stelle am Dateianfang.

Ausgabe[Bearbeiten]

Die Ausgabe lässt sich ziemlich simpel realisieren, wir geben einfach das von uns gewünschte Format auf dem Ausgabestream aus, den wir mittels Parameter erhalten. Dann geben wir den Stream zurück. Beachten Sie allerdings, dass Sie die Headerdatei „iostream“ inkludieren müssen, damit Sie die Standardstreams überladen können.

Nuvola-inspired-terminal.svg
1 #include <iostream>
2 
3 std::ostream& operator<<(std::ostream &os, Bruch const &bruch){
4     return os << '(' << bruch.zaehler() << '/' << bruch.nenner() << ')';
5 }

Eingabe[Bearbeiten]

Die Eingabe ist etwas schwieriger. Wir müssen sicherstellen, dass das von uns vorgegebene Format eingehalten wird und falls nötig, den Eingabestream auf einen Fehlerstatus zu setzen.

Nuvola-inspired-terminal.svg
 1 #include <iostream>
 2 
 3 std::istream& operator>>(std::istream &is, Bruch &bruch){
 4     char tmp;
 5     int zaehler;
 6     unsigned int nenner;
 7     is >> tmp;
 8     if(tmp == '('){
 9         is >> zaehler;
10         is >> tmp;
11         if(tmp == '/'){
12             is >> nenner;
13             is >> tmp;
14             if(tmp == ')'){
15                 bruch = Bruch(zaehler, nenner);
16                 return is;
17             }
18         }
19     }
20     is.setstate(std::ios_base::failbit);
21     return is;
22 }

Wie Sie sehen können, wird diesmal eine nicht-konstante Referenz auf einen Bruch übergeben, da dieser ja geändert wird, wenn man ihm einen neuen Wert zuweist. Da die Klasse Bruch keine Möglichkeit bereitstellt, zaehler oder nenner einzeln zu ändern, erstellen wir nach dem Einlesen beider einen entsprechenden Bruch und weisen ihn an unseren zu. Auf diese Weise stellen wir auch sicher, dass sich an dem Bruch nichts verändert, wenn während des Einlesens irgendetwas schief geht. Falls etwas daneben geht, wird das failbit gesetzt und anschließend der Stream zurückgegeben.