Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«

Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«

Um in der Programmierung mit C mehr Möglichkeiten zu haben, ist es wichtig, Kenntnisse über die formatierte Ein- und Ausgabe zu haben. In diesem Artikel werden die Funktionen scanf() und printf() vorgestellt, die ideal für den Einstieg sind. Es ist jedoch wichtig, zu beachten, dass diese Funktionen sicherheitskritisch sind und mit Vorsicht verwendet werden sollten.

Formatierte Eingabe mit »scanf()«

Zu Beginn möchten wir einen Hinweis für absolute Anfänger in C geben. Es ist normal, dass Ihnen in diesem Kapitel einige Dinge unklar erscheinen. Aber sobald Sie das Buch komplett durchgelesen haben, werden sich viele Fragen von selbst klären. Versprochen!

Schauen wir uns zunächst die Syntax dieser Funktion an:

scanf()

Mit der Funktion scanf() können Werte unterschiedlicher Datentypen formatiert eingelesen werden. Standardmäßig wird von der Standardeingabe (stdin) gelesen, was normalerweise die Tastatur bedeutet. Hier ist ein Beispiel für die Verwendung der Funktion scanf():

int zahl;
scanf("%d", &zahl);

Wenn das Programm korrekt abläuft, wird der Benutzer nach einer Zahl gefragt. Nachdem der Benutzer eine Zahl eingegeben und die Eingabetaste gedrückt hat, gibt das Programm die eingegebene Zahl auf dem Bildschirm aus und wird beendet.

Abbildung 4.1: Eine einfache Zahleneingabe mit »scanf()«

Die Funktion scanf() ähnelt in der Syntax der Funktion printf(). Beide verwenden Klammern und Hochkommata zur Formatierung. Das Formatzeichen %d steht hier für die formatierte Eingabe einer dezimalen Zahl. Aber was bedeutet das Zeichen “&”?

Der Adressoperator “&”

Es ist hilfreich, den Adressoperator “&” zu verstehen, auch wenn dies Thema der Zeiger ist, das später im Buch behandelt wird. Wenn Ihnen dieser Abschnitt etwas fremd erscheint, machen Sie sich keine Sorgen.

LESEN  Petroleumöfen – Die unabhängige Heizlösung für jeden Raum

Eine Variable kann in vier Teile unterteilt werden:

  • Datentyp
  • Variablenname
  • Speicheradresse
  • Wert

Im obigen Programmbeispiel ist der Datentyp ein int und der Name ist zahl. Die Speicheradresse wird zur Laufzeit zugewiesen und kann nicht beeinflusst werden. Nehmen wir an, die Speicheradresse ist 0000:123A. Wenn wir nun beispielsweise die Zahl 5 eingeben, wird der Speicherplatz wie folgt belegt:

Abbildung 4.3: Eine Variable im Speicher

Das “&”-Zeichen ist der Adressoperator. Damit wird der Variablen zahl vom Typ int die Speicheradresse 0000:123A zugewiesen und der Wert 5 wird gespeichert. Denken Sie daran, dass Sie jemandem eine E-Mail senden können, ohne die E-Mail-Adresse anzugeben?

Probleme und deren Behandlung mit »scanf()«

Ein häufiges Problem bei der Verwendung von scanf() ist die Pufferung. Je nach System und Anwendung kann dies zeilenweise oder vollständig gepuffert sein. Dies gilt jedoch nicht für die Standardfehlerausgabe (stderr), die immer ungepuffert sein muss.

Um das Problem zu verdeutlichen, betrachten wir folgendes Programm:

char buchstabe;
scanf("%c", &buchstabe);

Das Ergebnis könnte wie folgt aussehen:

Abbildung 4.4: Ein mögliches Problem mit »scanf()« unter Linux

Was ist passiert? Warum wird der zweite Buchstabe übersprungen? Das Problem liegt in der Pufferung. In C gibt es keinen Befehl, um das letzte Zeichen zu entfernen.

Es wurde zum Beispiel der Buchstabe “a” eingegeben und die Eingabetaste gedrückt. Das Newline-Zeichen (ASCII-Code = 10) befindet sich immer noch im Puffer der Standardeingabe und wird automatisch für das zweite Zeichen verwendet. Was kann man dagegen tun? Hier sind einige Möglichkeiten, aber sie sind auch abhängig vom System:

Möglichkeit 1

Verwenden Sie die Funktion fflush(), um den Tastaturpuffer zu leeren. Dies funktioniert möglicherweise nicht auf jedem Betriebssystem.

Möglichkeit 2

Verwenden Sie eine do-while-Schleife und entfernen Sie das Newline-Zeichen aus dem Puffer:

char buchstabe;
do {
    scanf("%c", &buchstabe);
} while (buchstabe != 'n');

Möglichkeit 3

Verwenden Sie scanf() gar nicht erst (was aus Sicherheitsgründen empfohlen wird) und greifen Sie auf andere Funktionen zur Standardeingabe zurück. Es ist beispielsweise ideal, die Funktion fgets() zum Einlesen zu verwenden und die Eingabe mit der Funktion sscanf() in ein passendes Format zu konvertieren.

char eingabe[50];
fgets(eingabe, sizeof(eingabe), stdin);
sscanf(eingabe, "%d", &zahl);

Die Funktion scanf() wird in diesem Buch noch öfter verwendet. Wenn etwas nicht wie erwartet funktioniert, beziehen Sie sich auf die in diesem Kapitel gezeigten Möglichkeiten.

LESEN  Sumpfschachtelhalm: Erkennung und Unterscheidung vom Ackerschachtelhalm

Überprüfen auf das richtige Format

Um sicherzugehen, dass der Benutzer das Richtige eingegeben hat, können Sie den Rückgabewert von scanf() überprüfen:

int ergebnis = scanf("%c %d", &buchstabe, &zahl);
if (ergebnis == 2) {
    printf("Die Eingabe war korrekt!");
} else {
    printf("Die Eingabe war fehlerhaft!");
}

Der Rückgabewert von scanf() ist immer die Anzahl der erfolgreich gelesenen Werte. Der Wert 0 wird zurückgegeben, wenn das geforderte Format nicht übereinstimmt. In diesem Beispiel erwartet scanf() die Eingabe eines Zeichens (%c) und einer Dezimalzahl (%d). Wenn beide Eingaben korrekt gemacht wurden, sollte die printf()-Anweisung den Wert “2” ausgeben.

Mit dieser Überprüfung können Sie das Programm verbessern, um ein undefiniertes Verhalten zu verhindern:

if (scanf("%c %d", &buchstabe, &zahl) != 2) {
    printf("Die Eingabe war fehlerhaft!");
    return 1; // Fehlercode
}

Wenn die erste Eingabe von scanf() bereits fehlerhaft ist, wird die zweite Eingabe ignoriert. Daher gibt scanf() dann 0 zurück, da keine Zeichen gespeichert werden konnten.

Abschließend lässt sich sagen, dass die Funktion scanf() zeichenweise Eingabefelder einliest. Für jedes Eingabefeld muss eine Adresse vorhanden sein, die mit dem Datentyp des Feldes übereinstimmt. Der Rückgabewert von scanf() gibt die Anzahl der erfolgreich eingelesenen Felder zurück. Wenn keine Felder korrekt eingelesen wurden, gibt scanf() den Wert 0 zurück. Wenn bereits bei der Eingabe ein Fehler auftritt, bevor überhaupt Daten gelesen wurden, wird EOF zurückgegeben.

Folgende Zeichen werden bei scanf() als Eingabefelder akzeptiert:

  • alle Zeichen bis zum nächsten Whitespace (Leerzeichen, Tabulator, Zeilenumbruch)
  • alle Zeichen bis zur angegebenen Feldbreite von n
  • alle Zeichen bis zum ersten Zeichen, das nicht in das entsprechende Format konvertiert werden konnte

Hinweis: In diesem Artikel wurde nur ein kleiner Teil der Funktionalitäten und Möglichkeiten von scanf() behandelt. Es gibt noch viele weitere Details, die Sie in diesem Buch nachschlagen können.

LESEN  Fake Freckles: So zauberst du sie ganz natürlich

Ihre Meinung

Wir hoffen, Ihnen hat dieser Artikel gefallen! Wir freuen uns immer über Ihr Feedback. Schreiben Sie uns gerne Ihre Meinung per E-Mail an kommunikation@rheinwerk-verlag.de.