# Ein- und Ausgabe

- Terminal
- Dateien
- Pipes

## Terminal

Um Ausgaben auf die Benutzerschnittstelle zu schreiben, wird am einfachsten die Funktion `print` verwendet. Es gibt außerdem noch die Funktion `printf`, die als Argument zunächst eine Zeichenkette erwartet, die das gewünschte Ausgabeformat beschreibt, und anschließend die entsprechenden Variablen (im wesentlichen identisch zur Funktion `printf()` in C). Eine interaktive Eingabe kann über `<STDIN>` eingelesen werden.

Beispiel:

`#!/usr/local/bin/perl -w use strict; print "Name : "; my $name = <STDIN>; chomp($name); printf("Hallo, %s !\n",$name);`

`Name : Eike Hallo, Eike !`

Hier wurde noch die Funktion `chomp()` benutzt; sie entfernt von der Zeichenkette im Argument den Zeilenvorschub "`\n`", mit dem die Eingabe von der Tastatur abgeschlossen wird.

Bei der Zuweisung von `<STDIN>` wird (wie oben im skalaren Kontext) jeweils eine Zeile, d.h., bis zum nächsten Vorschub, eingelesen.

Im Formatierungsstring von `printf` hat das Prozentzeichen "`%`" eine besondere Bedeutung, indem es ein Ausgabeformat einleitet. Die wichtigsten Formate zeigt folgende Tabelle:

> Format | Beschreibung
> --- | ---
> `%c` | einzelnes Zeichen
> `%s` | Zeichenkette
> `%d`, `%i` | Ganzzahl
> `%o` | Oktalzahl
> `%x` | Hexadezimalzahl
> `%f` | Gleitkommazahl
> `%e` | wissenschaftliche Schreibweise
> `%%` | explizites Prozentzeichen

Zwischen "`%`" und dem Formatzeichen kann die gewünschte Ausgabebreite (nur vergrößern möglich, also z.B. Auffüllen mit Leerzeichen) bzw. Genauigkeit angegeben werden:

`#!/usr/local/bin/perl -w use strict; printf "%d\n",12345; printf "%7d\n",12345; printf "%4.0f\n",123.45; printf "%4.1f\n",123.45; printf "%4.3f\n",123.45; printf "%%%8s%%\n","Hallo";`

`12345 12345 123 123.5 123.450 % Hallo%`

[Seitenanfang]

## Dateien

Will man Daten von einem File lesen, so muß diese Datei erst geöffnet und ihr ein "Filehandle" zugewiesen werden. Anschließend kann über dieses Filehandle auf die Daten zugegriffen werden. Insbesondere beim Umgang mit Dateien (wie auch bei anderen Systemfunktionen) sollte immer anhand des Rückgabewertes kontrolliert werden, ob der Aufruf erfolgreich war.

Beispiel:

`#!/usr/local/bin/perl -w use strict; my $rw = open(FILE,"demo.dat"); if(not defined($rw)) { die "Fehler beim Öffnen der Datei: $!\n"; } while(defined(my $i = <FILE>)) { print $i } close(FILE);`

Die Funktion `open()` erwartet als erstes Argument das sogenannte Filehandle, das per Konvention aus Großbuchstaben besteht. Anschließend wird die zu öffnende Datei angegeben.

Obiges Programm ordnet über `<FILE>` der Variablen `$i` nacheinander jeweils eine Zeile der geöffneten Datei zu. Ist das Dateiende erreicht, kann keine Zuordnung mehr stattfinden, daher bleibt dann der Wert von `$i` undefiniert; dies wird durch die Funktion `defined()`überprüft ("Lese solange Zeilen ein wie `$i` einen definierten Wert besitzt"). Nach Beendigung des Lesevorgangs wird die Datei mit `close()` wieder geschlossen; fehlt diese Funktion, so werden bei Programmende automatisch alle noch offenen Files geschlossen.

Im Falle eines Fehlers beim Dateizugriff ist der Rückgabewert von `open()` nicht definiert, und die spezielle Variable `$!` enthält die Fehlermeldung des Betriebssystems.

Kürzer und einprägsamer läßt sich die Überprüfung des Rückgabewertes wie folgt schreiben:

`open(FILE,"demo.dat") or die "Fehler beim Öffnen der Datei: $!\n";`

Um eine Datei zum Schreiben zu öffnen, muß dies durch ein "`>`" vor dem Dateinamen angegeben werden.

Beispiel:

`#!/usr/local/bin/perl -w use strict; open(LESEN,"alt.dat") or die "Fehler beim Öffnen von 'alt.dat': $!\n"; open(SCHREIBEN,"> neu.dat") or die "Fehler beim Öffnen von 'neu.dat': $!\n"; while(defined(my $i = <LESEN>)) { print SCHREIBEN $i } close(LESEN); close(SCHREIBEN) or die "Fehler beim Schließen von 'neu.dat': $! \n"`

Hier wird also der gesamte Inhalt von `alt.dat` gelesen und in die Datei `neu.dat` geschrieben. Zur Ausgabe auf ein File wird der Funktion `print` als erstes das Filehandle übergeben.

Beim Schreiben in eine Datei empfiehlt sich auch eine Überprüfung des Rückgabewertes von `close()`, um sicherzugehen, daß der Schreibvorgang erfolgreich abgeschlossen wurde.

Außer den vom Programmierer definierten Filehandles gibt es drei Standard-Handles:

- STDIN: Eingabe von Tastatur
- STDOUT: Ausgabe auf Terminal
- STDERR: Ausgabe von Fehlermeldungen (i.a. auch Terminal)

Das meist ohne Filehandle verwendete "`print`" ist also eigentlich nur eine Abkürzung für "`print STDOUT`".

Ebenso ist die Richtung des Datentransfers (Lesen oder Schreiben) an die entsprechenden Shell-Konventionen angelehnt. Zum Lesen einer Datei kann auch

> `open(LESEN,"< alt.dat");`

geschrieben werden.

Will man Daten nur an die Daten eines bestehenden Files anhängen, so schreibt man "`>>`" vor den Dateinamen:

> `open(SCHREIBEN,">> neu.dat");`

[Seitenanfang]

## Pipes

Außer mit Dateien kann ein Perl-Programm auch Daten direkt mit Programmen austauschen (sofern dies vom Betriebssystem - wie z.B. UNIX - unterstützt wird). Dies funktioniert mit Hilfe von sogenannten Pipes. Zur Markierung wird dabei das Pipe-Symbol (ein senkrechter Strich "`|`") verwendet.

Beispiel:

`#!/usr/local/bin/perl -w use strict; open(DATUM,"date |"); # date : Datumsfunktion print <DATUM>; close(DATUM) or die "Fehler bei Ausführung von 'date'\n"; open(WORT,"| wc > wort.dat"); # wc : Zählprogramm print WORT "eins zwei drei vier\n"; close(WORT) or die "Fehler bei Ausführung von 'wc'\n";`

Im ersten Teil des Programms wird unter UNIX der Befehl `date` ausgeführt und das Ergebnis an das Perl-Skript geliefert. `print` gibt somit Datum und Uhrzeit des Systems aus.

Im zweiten Teil des Programms wird die Zeichenkette "`eins zwei drei vier`" an das Programm `wc` übergeben, das dann die Zeichen, Wörter und Zeilen der Eingabe liest und das Ergebnis (1 Zeile, 4 Wörter, 20 Zeichen) in die Datei `wort.dat` schreibt (das Öffnen von Ein- und Ausgabepipes in einem Filehandle gleichzeitig ist nicht möglich).

Bei Pipes ist es wichtig, den Rückgabewert von `close()` (und nicht den von `open()`) zu überprüfen, um festzustellen, ob das Kommando ausgeführt werden konnte.

[Seitenanfang]

Autor: Eike Grote | Version: 2.02 (30.5.2005)