Programmiersprache C/C++

Formatierte Eingabe

  #include <stdio.h>

  int scanf(const char *format [,parameter]...);
Parameter:
  format      Formatierungsanweisungen
  parameter   optionale Parameter
scanf liest Eingaben in formatierter Form von stdin und erwartet im Minimalfall einen String mit Formatierungsanweisungen (Parameter format), über den die Anzahl der Eingaben und ihre Formate festgelegt werden. Gelesene Eingaben werden in den Variablen der Parameterliste gespeichert:
Nach der Analyse der ersten Formatanweisung wird eine Eingabe gelesen, konvertiert und im korrespondierenden Parameter gespeichert (der seinerseits auf eine Variable entsprechenden Typs zeigen muß); danach wird format auf die nächste Anweisung hin analysiert usw.

Der Parameter format kann die folgenden Elemente enthalten:

Der als format übergebene String wird von links nach rechts auswertet. scanf erwartet, daß Zeichen außerhalb von Formatierungsanweisungen mit entsprechenden Zeichengruppen der Eingabe zusammenfallen (die ihrerseits gelesen, aber nirgendwo gespeichert werden). Wenn die Funktion bei der Bearbeitung einer Formatierungsanweisung auch nur ein einzelnes Zeichen in der Eingabe vorfindet, das nicht in das erwartete Format paßt, wird die Operation abgebrochen; dieses Zeichen bleibt im Eingabepuffer von stdin. Bereits besetzte Variablen bleiben bei diesem Abbruch im besetzten Zustand, noch nicht bearbeitete Variablen der Parameterliste bleiben undefiniert.

scanf ordnet jeder Formatierungsanweisung ein Eingabefeld zu, das zeichenweise analysiert wird - auf den Abschluß der Analyse folgt die Speicherung des Ergebnisses über den korrespondierenden Parameter.

Rückgabewert:
scanf liefert die Anzahl der fehlerfrei konvertierten und zugeordneten Eingabefelder zurück, wobei mittel "%*" adressierte Eingabefelder nicht in diese Zählung eingehen.
Wenn die Funktion überhaupt keine Eingabe erhält (d.h. vor dem Lesen des ersten Feldes auf das Dateiende trifft), ist das Ergebnis der Wert EOF.

Typangaben für scanf

Zeichen   Art des erwarteten Wertes             Typ des Parameters
-----------------------------------------------------------------------
 d        dezimaler Integer,                    Zeiger auf int
          opt. Vorzeichen
 o        oktaler Integer                       Zeiger auf int
 x        hexadezimaler Integer                 Zeiger auf int
 i        dezimaler, hexadezimaler oder         Zeiger auf int
          oktaler Integer
 u        vorzeichenloser dezimaler Integer     Zeiger auf unsigned int
 e, E     Fließkommawert, der sich aus einem    Zeiger auf float
 f        optionalen Vorzeichen, einer oder
 g, G	  mehreren Ziffern mit einem optionalen
          Dezimalpunkt, einem optionalen 
          Exponenten ("e" oder "E") und einem
          darauffolgenden vorzeichenbehafteten
          Integer zusammensetzt.	
 c        Zeichen. Erfaßt auch weiße            Zeiger auf char bzw. 
          Leerzeichen, die normalerweise          char-Array für %nc
          übersprungen werden. Zum Lesen eines
          "echten" Zeichens sollte man %1s
          benutzen, zum Lesen einer bestimmten
          Zahl beliebiger Zeichen die Angabe
          %nc, wobei n für die Anzahl zu
          lesender Zeichen steht. Das bei
          diesem Aufruf erzeugte char-Array
          bekommt kein abschließendes
          NULL-Zeichen!	
 s        String                                Zeiger auf ein char-Array,
                                                das ausreichend Platz zur
                                                Speicherung der Zeichenfolge
                                                inklusive eines von scanf
                                                automatisch angehängten
                                                NUL-Zeichens bieten muß.
 n        -- (nichts)                           Zeiger auf einen int,
                                                in dem die Anzahl der bis
                                                jetzt in diesem Aufruf von
                                                scanf gelesenen Zeichen
                                                gespeichert wird.
scanf ordnet jeder Formatierungsanweisung ein Eingabefeld zu, das zeichenweise analysiert wird - auf den Abschluß der Analyse folgt die Speicherung des Ergebnisses über den korrespondierenden Parameter.
Ein Eingabefeld umfaßt: scanf liest bei fehlerfreier Ausführung grundsätzlich komplette Eingabezeilen, d.h. arbeitet jeweils bis zu einem Zeilenvorschub.
(Da Zeilenvorschübe innerhalb einer Eingabe in die Klasse "weiße Leerzeichen" fallen, kann ein Aufruf der Funktion allerdings ohne weiteres mehrere Eingabezeilen lesen.) Wenn eine Eingabe mehr separate Felder enthält, als aufgrund der Formatierungsanweisungen in format zu erwarten wäre, dann liest die Funktion die restlichen Felder (bis zum jeweils nächsten Zeilenvorschub) und wertet sie aus, speichert die Ergebnisse dieser Konvertierungen aber nicht.
Enthält der Parameter format mehr Formatierungsanweisungen, als scanf beim entsprechenden Aufruf Zeiger auf Variablen übergeben bekommt, sind die Resultate unbestimmt.

Formatierungsanweisungen

Anweisungen dieser Art dienen als Platzhalter für einzulesende Werte. Sie beginnen grundsätzlich mit einem Prozentzeichen und lassen sich durch das folgende Syntaxdiagramm darstellen:

  %[*] [Breite] [{F | N}] [{h | l}]Typ
Jedes dieser Felder besteht entweder aus einem einzelnen Zeichen oder aus einem numerischen Wert. In ihrer einfachsten Form setzt sich eine Formatierungsanweisung lediglich aus dem Prozentzeichen und dem Feld Typ zusammen (Beispiel: %s für Strings, %d für dezimale Integer). Das Feld Typ ist als einziges obligatorisch, legt sozusagen den Grundtyp des zu konvertierenden Wertes fest.

Wenn auf ein Prozentzeichen ein Zeichen folgt, das scanf nicht als Formatierungsanweisung interpretieren kann, dann werden sämtliche Zeichen bis zum nächsten Prozentzeichen als normale Folge betrachtet, d.h. übersprungen. Aus diesem Grund läßt sich ein Prozentzeichen innerhalb von format einfach mit "%%" angeben.
Ein Sternchen ("*") direkt hinter dem Prozentzeichen teilt scanf mit, daß das nächste Eingabefeld zwar in einem bestimmten Format erwartet und auch entsprechend ausgewertet, aber nicht gespeichert wird. Das Feld Breite legt über einen positiven Integerwert fest, wie viele Zeichen scanf im Rahmen der aktuellen Konvertierung maximal von stdin einliest:
Über eine Angabe wie "%3d" ließe sich beispielsweise die Eingabe eines ganzzahligen Wertes mit maximal drei Ziffern bestimmen. Sollte ein Eingabefeld mehr als Breite Zeichen haben, werden überzählige Zeichen dem jeweils nächsten Feld zugeordnet; hat des weniger als die gewünschte Zeichenzahl (d.h. wird es vorzeitig durch ein weißes Leerzeichen oder ein anderes Zeichen beendet), dann bleibt die Festlegung der Breite ohne weitere Wirkung.

Das Präfix l teilt scanf mit, daß die korrespondierende Variable eine long-Variante des Grundtyps darstellt (long int bzw. double bei Gleitßpunktwerten), h steht für short-Varianten dieser Typen.
Die Typangaben d, i, n, o, x und u lassen sich sowohl mit h als auch mit l kombinieren; l ist zusätzlich für die Typangaben e, f und g verwendbar.
scanf interpretiert weiße Leerzeichen normalerweise auch bei der Eingabe von Strings ("%s") als Ende des jeweiligen Feldes - weshalb derartige Strings keine Leerzeichen enthalten dürfen. Die Alternative besteht in der Angabe einer mit eckigen Klammern eingeschlossenen Zeichenmenge anstelle des Zeichens s, wobei hier sowohl mit Aufzählungen als auch mit Ausschlüssen gearbeitet werden kann:

Die Regeln zur Angabe von Bereichen sind recht einfach gehalten: das Zeichen vor dem Bindestrich (-) muß einen ASCII-Code haben, der mindestens um eins niedriger ist als der des auf den Bindestrich folgenden Zeichens; der Bindestrich darf weder das erste noch das letzte Zeichen der Aufzählung sein; das Zeichen vor und das Zeichen nach dem Bindestrich muß jeweils den Beginn bzw. das Ende eines Bereichs darstellen.
In allen anderen Fällen wird der Bindestrich selbst als Zeichen (und nicht als Bereichsangabe) gewertet. Einige Beispiele dazu:
  %[-+*/]       die vier arithmetischen Operatoren
  %[z-a]        die Zeichen "z", "-" und "a"
  %[+0-9-A-F]   das Zeichen "+", die Ziffern von 0 bis 9,
                das Zeichen "-" und die Buchstaben von A bis F
  %[+0-9A-F-]   genau dieselben Zeichen wie im vorigen Beispiel

  %[^-0-9+A-F]  sämtliche Zeichen außer "-", den Ziffern 0 bis 9,
                dem Zeichen "+" und den Buchstaben A bis F
Bereichsangaben über Bindestriche stellen übrigens eine allgemein übliche Erweiterung von scanf dar, die aber nicht durch den ANSI-Standard abgedeckt ist.

  #include <stdio.h>

  int main(void)
  {
    char letter_1, letter_2, letter_3;
    int year;

    printf("Geben Sie 3 Zeichen als Nickname ein : ");
    scanf("%c%c%c", &letter_1, &letter_2, &letter_3);

    printf("Geben Sie das aktuelle Jahr ein : ");
    scanf("%d", &year);

    printf("Hallo, %c%c%c ! %d ist ein gutes Jahr um C zu lernen!\n",
                letter_1, letter_2, letter_3, year);

    return (0);
  }
Testergebnisse:
  Geben Sie 3 Zeichen als Nickname ein : 007
  Geben Sie das aktuelle Jahr ein : 1996
  Hallo, 007 ! 1996 ist ein gutes Jahr um C zu lernen!

  Geben Sie 3 Zeichen als Nickname ein : 0077
  Geben Sie das aktuelle Jahr ein : Hallo, 007 ! 7 ist ein gutes Jahr um C zu lernen!

  Geben Sie 3 Zeichen als Nickname ein : 007
  Geben Sie das aktuelle Jahr ein : nein
  Hallo, 007 ! 0 ist ein gutes Jahr um C zu lernen!

  Geben Sie 3 Zeichen als Nickname ein : bb
  Geben Sie das aktuelle Jahr ein : 1996
  Hallo, bb
   ! 1996 ist ein gutes Jahr um C zu lernen!
Bemerkung:
Das Verhalten bei fehlerhafter Eingabe kann systemspezifisch sein !


Zurück zum Menü
Zurück zur vorigen Seite Weiter zur nächsten Seite

P. Böhme, 15.02.1996