Eingabe und Ausgabe
Alles fließt.
– Heraklit
Das EVA-Prinzip
Computer sind Maschinen zur elektronischen Datenverarbeitung. Dabei ist der Anwendungszweck des Computers nicht von vornherein festgelegt. Ein Computer kann mit Programmen gesteuert werden, die bei der Konstruktion des Computer noch gar nicht existierten. Software, also Betriebssystem und Anwenderprogramme, machen die Hardware so vielseitig einsetzbar.
Der Zweck von Programmen ist, auf eingehende Signale, die Eingabe, zu reagieren. Das Programm muss Daten entgegennehmen, verarbeiten und soll dann eine entsprechende Ausgabe erzeugen. Als Gerät zur Eingabe dient uns die Tastatur. Tastatur und Bildschirm bilden zusammen die Konsole. Die Bezeichnung stammt aus der Zeit, als Großrechner noch über Fernschreibmaschinen bedient wurden. Andere Ein- und Ausgabegeräte erfordern Programmierkenntnisse, die über diese Einführung hinausgehen.
In C++ geschriebene Programme verfügen neben einem Ausgabestrom cout („console output“) auch über einen Eingabestrom cin („console input“), wie dieses Programm zeigt:
//> basics/quadrat.cpp
import std;
int main()
{
int zahl;
std::cin >> zahl;
int ergebnis = zahl * zahl;
std::cout << ergebnis << '\n';
}Startet das Programm, wartet es auf eine Nutzereingabe, die mit der Entertaste abgeschlossen werden muss. Die einzugebende Zahl landet dann in einem dafür vorgesehenen Speicherplatz, einer Variable mit dem Namen zahl. Deren Wert wird dann zum ergebnis verarbeitet und schließlich ausgegeben. Die Doppelpfeile >> und << geben die Richtung der Datenströme an.
Gibt der Nutzer etwas ein, das keine Zahl darstellt, verhält sich das Programm fehlerhaft, entsprechend dem GIGO-Prinzip („garbage in, garbage out“): Gibst du Müll rein, kommt auch Müll raus.
Umlenken von Dateiströmen
Die Standard-Ein- und -Ausgabeströme eines Programms können vom Betriebssystem an andere Dateien oder Datenströme gekoppelt werden. Steht die Eingabe
13in einer Datei namens input.txt, erzeugt der Aufruf
quadrat < input.txt > output.txt
eine andere Datei namens output.txt mit dem Inhalt
169
Besonders für umfangreiche Datenmengen ist das vorteilhaft.
Debuggen mit Leuchtspur
Ein dritter Datenstrom namens cerr („console error“) kann für Fehlermeldungen genutzt werden.
//> basics/quadrat_cerr.cpp
import std;
int main()
{
int zahl;
if (std::cin >> zahl)
{
int ergebnis = zahl * zahl;
std::cout << ergebnis << '\n';
}
else
{
std::cerr << "fehlerhafte Eingabe: Ganzzahl erwartet\n";
}
}Die Fehlermeldungen lassen sich in einer weitere Datei umlenken:
quadrat < input.txt > output.txt 2> fehlermeldung.txt
Manchmal verhält sich ein komplexeres Programm nicht wie erwartet. Dann möchte ich wissen, welche Programmstelle noch erreicht wurde und welche nicht. Dazu baue ich an geeigneten Stellen Ausgaben auf den Standardfehlerstrom ein. Das Buch The Pragmatic Programmer1 empfiehlt als Tipp Nr. 15: „Use tracer bullets to find the target.“ Dies hilft, Fehler zu lokalisieren.
Aufgaben
- Erzeuge ein einfaches Programm mit Ein- und Ausgabe. Starte es auf der Konsole. Wie reagiert es auf deine Eingaben?
- Leite Daten aus einer Datei in das Programm. Lenke die Ausgabe in eine Datei um. Was geschieht dann mit einer Ausgabe auf den Standardfehlerstrom?
- Worin unterscheiden sich die Inhalte der Ausgabedatei bei Umlenkung mit
>und mit>>bei mehrmaligem Ausführen?
Anmerkungen
-
Andrew Hunt, David Thomas: The Pragmatic Programmer: From Journeyman To Master. (2005) ↩