Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch für Linux, Unix und Windows
– 2., aktualisierte und erweiterte Auflage 2006
Buch: C von A bis Z

C von A bis Z
1.116 S., mit CD, Referenzkarte, 39,90 Euro
Galileo Computing
ISBN 3-89842-643-2
gp Kapitel 5 Formatierte Eingabe mit scanf()
  gp 5.1 Der Adressoperator »&«
  gp 5.2 Probleme und deren Behandlung mit scanf()
    gp 5.2.1 Möglichkeit 1
    gp 5.2.2 Möglichkeit 2
    gp 5.2.3 Möglichkeit 3
  gp 5.3 Format prüfen
  gp 5.4 Zusammenfassung scanf()


Galileo Computing - Zum Seitenanfang

5.2 Probleme und deren Behandlung mit scanf()  downtop

Ein häufiges Problem, das auftritt, wenn Sie scanf() für die Eingabe verwenden, ist die Pufferung. Diese ist je nach System und Anwendung zeilen- oder vollgepuffert. Dies gilt wiederum nicht für die Standardfehlerausgabe (stderr), die laut ANSI C niemals vollgepuffert sein darf. Bevor ich dies weiter erkläre, folgendes Programm zum Testen:

/* scanf2.c */
#include <stdio.h>
int main(void) {
   char a,b,c;
   printf("1. Buchstabe : ");
   scanf("%c",&a);
   printf("2. Buchstabe : ");
   scanf("%c",&b);
   printf("3. Buchstabe : ");
   scanf("%c",&c);
   printf("Sie gaben ein : %c %c %c ",a,b,c);
   return 0;
}

Folgendes könnte nun vom Programm auf den Bildschirm ausgegeben werden:

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 5.4   Ein mögliches Problem mit scanf unter Linux

Was ist hier passiert? Warum wird der zweite Buchstabe immer übersprungen? Wie gesagt, das Problem ist hier die Pufferung. Und in C gibt es keinen Befehl (wie etwa chomp bei Perl), um das letzte Zeichen zu entfernen.

In diesem Beispiel wurde als erster Buchstabe »a« eingegeben und (¢) gedrückt. Dieses (¢) (ASCII-Code = 10 = \n = newline) befindet sich immer noch im Puffer der Standardeingabe und wird automatisch für das zweite Zeichen verwendet. Was können Sie dagegen tun? Hierzu ein paar Möglichkeiten, die allerdings auch systemabhängig sind:


Galileo Computing - Zum Seitenanfang

5.2.1 Möglichkeit 1  downtop

Sie benutzen die Funktion fflush() zum Entleeren des Tastaturpuffers. Möglicherweise gelingt dies nicht auf jedem Betriebssystem (speziell nicht unter Linux):

/* scanf3.c */
#include <stdio.h>
int main(void) {
   char a,b,c;
   printf("1. Buchstabe : ");
   scanf("%c",&a);
   fflush(stdin);
   printf("2. Buchstabe : ");
   scanf("%c",&b);
   fflush(stdin);
   printf("3. Buchstabe : ");
   scanf("%c",&c);
   printf("Sie gaben ein : %c %c %c ",a,b,c);
   return 0;
}

Galileo Computing - Zum Seitenanfang

5.2.2 Möglichkeit 2  downtop

Sie benutzen eine do while-Schleife und ziehen das Newline-Zeichen aus dem Puffer heraus:

/* scanf4.c */
#include <stdio.h>
int main(void) {
   char a,b,c;
   printf("1. Buchstabe : ");
   do {scanf("%c",&a);} while ( getchar() != '\n' );
   printf("2. Buchstabe : ");
   do {scanf("%c",&b);} while ( getchar() != '\n' );
   printf("3. Buchstabe : ");
   do {scanf("%c",&c);} while ( getchar() != '\n' );
   printf("%c %c %c\n",a,b,c);
   return 0;
}

Mehr zur do while-Schleife finden Sie in Kapitel 10. Dieses Beispiel lässt sich natürlich auch mit einer while()-Schleife als Makro verpackt realisieren:

#define Fflush(int_keyboard_buffer)\
   while(( (int_keyboard_buffer) = getchar()) != '\n')

Mehr zu diesem Beispiel erfahren Sie in Kapitel 12, Präprozessor-Direktiven.


Galileo Computing - Zum Seitenanfang

5.2.3 Möglichkeit 3  toptop

Sie verwenden scanf() erst gar nicht und greifen auf eine der vielen anderen Standardeingaben-Funktionen zurück. Ideal wäre es beispielsweise, die Funktion fgets() zum Einlesen zu verwenden und diese Eingabe mit der Funktion sscanf() in ein entsprechendes Format zu konvertieren. Entsprechendes Beispiel könnte so aussehen:

/* scanf5.c */
#include <stdio.h>
int main(void) {
   char ch;
   char buf[2];
   printf("Ein Zeichen bitte : ");
   fgets(buf, 2, stdin);
   sscanf(buf, "%c", &ch);
   printf("Das Zeichen : %c\n",ch);
   return 0;
}

Hinweis   Im Laufe dieses Buchs wird noch des Öfteren die Funktion scanf() verwendet. Sollte etwas nicht so funktionieren, wie es sollte, beziehen Sie sich auf dieses Kapitel.



Achtung   Die Funktion scanf() ist nicht gegen einen Pufferüberlauf (Buffer Overflow) geschützt und somit unsicher, d.h., sie könnte für einen Hack des Programms durch eine andere Person missbraucht werden. Damit ist gemeint, dass die Funktion nicht die Anzahl der eingegebenen Zeichen überprüft und es damit zu Fehlern kommen kann bzw. ein Fehlverhalten von außen provoziert werden kann.


 << zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z
C von A bis Z
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-Programmierung


Zum Katalog: C/C++






 C/C++


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Reguläre Ausdrücke






 Reguläre Ausdrücke


Zum Katalog: Linux






 Linux


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de