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

13

in 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

  1. Erzeuge ein einfaches Programm mit Ein- und Ausgabe. Starte es auf der Konsole. Wie reagiert es auf deine Eingaben?
  2. Leite Daten aus einer Datei in das Programm. Lenke die Ausgabe in eine Datei um. Was geschieht dann mit einer Ausgabe auf den Standardfehlerstrom?
  3. Worin unterscheiden sich die Inhalte der Ausgabedatei bei Umlenkung mit >und mit >> bei mehrmaligem Ausführen?

Anmerkungen

  1. Andrew Hunt, David Thomas: The Pragmatic Programmer: From Journeyman To Master. (2005)