fgets() und gets() in der C-Programmierung

In der C-Programmierung sind fgets() und gets() zwei grundlegende Funktionen zum Erfassen von Eingaben des Benutzers. Beide dienen dem Einlesen von Daten aus dem Standardeingabestrom, der meistens die Tastatur ist, und deren Speicherung in einem Zeichenarray. Obwohl beide ähnliche Aufgaben erfüllen, existieren signifikante Unterschiede, die ihre Eignung für bestimmte Anwendungsfälle bestimmen. Dieser Artikel untersucht die Funktionsweise von fgets() und gets(), analysiert ihre Differenzen und erläutert, wann welche Funktion bevorzugt eingesetzt werden sollte.

Einführung in die Funktion fgets()

Die fgets() Funktion extrahiert eine vorgegebene Anzahl von Zeichen aus einem Datenstrom und legt diese in einem Zeichenarray ab. Sie arbeitet mit drei Parametern:

  • Zeichenarray: Die Speicherstelle, in der die gelesenen Daten hinterlegt werden.
  • Größenangabe: Die maximale Anzahl der einzulesenden Zeichen.
  • Datenstrom: Der Strom, aus dem gelesen wird (in der Regel stdin für die Standardeingabe).

Beispielcode:


#include <stdio.h>
#include <string.h>

int main() {
    char buffer[100];

    printf("Geben Sie einen Text ein: ");
    fgets(buffer, 100, stdin);

    printf("Eingabe: %s", buffer);

    return 0;
}

In diesem Beispiel liest fgets() bis zu 100 Zeichen aus der Standardeingabe und speichert diese im buffer Array. Das Newline-Zeichen (\n), das durch Drücken der Eingabetaste erzeugt wird, wird ebenfalls im Puffer gesichert.

Einführung in die Funktion gets()

Die Funktion gets() ist eine ältere Methode, die eine komplette Zeile aus der Standardeingabe aufnimmt und im übergebenen Zeichenarray speichert. Im Unterschied zu fgets() ignoriert gets() die Größenangabe des Arrays.

Beispielcode:


#include <stdio.h>
#include <string.h>

int main() {
    char buffer[100];

    printf("Geben Sie einen Text ein: ");
    gets(buffer);

    printf("Eingabe: %s", buffer);

    return 0;
}

Dieses Beispiel ähnelt dem vorigen, jedoch fehlt die Begrenzung der Eingabegröße.

Wesentliche Unterschiede zwischen fgets() und gets()

Die Hauptunterschiede zwischen fgets() und gets() sind:

  • Größenbeschränkung: fgets() limitiert die Anzahl der gelesenen Zeichen gemäß der angegebenen Größe, während gets() die komplette Eingabe entgegennimmt, ohne Rücksicht auf die Arraygröße.
  • Newline-Zeichen: fgets() behält das Newline-Zeichen (\n), wohingegen gets() es entfernt.
  • Sicherheit: gets() ist nicht sicher und birgt das Risiko von Pufferüberläufen. Dies liegt daran, dass keine Größenbeschränkung existiert und die Eingabe ohne Prüfung des verfügbaren Speicherplatzes in das Array geschrieben wird.

Die Sicherheitsbedenken bei gets()

Ein Pufferüberlauf entsteht, wenn mehr Daten in einen Puffer geschrieben werden, als dieser aufnehmen kann. Dies kann zu unerwarteten Programmfehlern, Datenkorruption oder sogar zu Sicherheitslücken führen. Da gets() keine Größenbeschränkung besitzt, ist das Risiko eines Pufferüberlaufs erheblich, wenn der Benutzer mehr Zeichen eingibt, als das Zeichenarray fassen kann.

Beispielcode zur Demonstration eines Pufferüberlaufs:


#include <stdio.h>
#include <string.h>

int main() {
    char buffer[100];

    printf("Geben Sie einen Text ein: ");
    gets(buffer);

    printf("Eingabe: %s", buffer);

    return 0;
}

Gibt der Nutzer mehr als 100 Zeichen ein, überschreibt gets() den Speicher außerhalb des Arrays buffer, was zu unvorhersehbarem Verhalten führen kann.

Wann sollte man fgets() einsetzen?

fgets() ist die sichere und empfohlene Wahl zum Einlesen von Benutzerdaten in C-Programmen. Sie bietet eine Größenbegrenzung, die Pufferüberläufe verhindert, und behandelt das Newline-Zeichen auf korrekte Weise.

Beispiel für die sichere Verwendung von fgets():


#include <stdio.h>
#include <string.h>

int main() {
    char buffer[100];

    printf("Geben Sie einen Text ein: ");
    fgets(buffer, 100, stdin);

    // Newline-Zeichen entfernen
    if (buffer[strlen(buffer) - 1] == '\n') {
        buffer[strlen(buffer) - 1] = '\0';
    }

    printf("Eingabe: %s", buffer);

    return 0;
}

Dieses Beispiel demonstriert, wie das Newline-Zeichen aus dem Array entfernt werden kann, um eine saubere Ausgabe zu gewährleisten.

Wann sollte man gets() vermeiden?

Die Funktion gets() sollte niemals verwendet werden, da sie eine Sicherheitslücke darstellt und zu Pufferüberläufen führen kann. Sie ist von C-Kompilern als veraltet markiert worden und sollte in der modernen C-Programmierung nicht mehr verwendet werden.

Schlussfolgerung

Die Funktionen fgets() und gets() sind für das Erfassen von Eingaben des Benutzers in C-Programmen vorgesehen. fgets() stellt jedoch die sicherere und zuverlässigere Option dar. gets() ist unsicher und sollte aufgrund des Risikos von Pufferüberläufen gemieden werden. Wenn in C-Programmen Benutzereingaben erfasst werden müssen, sollte immer fgets() zum Einsatz kommen.

FAQ

1. Kann ich gets() weiterhin nutzen, wenn die Größenbeschränkung des Arrays bekannt ist?

Nein, gets() bleibt auch bei bekannter Arraygröße unsicher. Es wird dringend geraten, stattdessen fgets() zu verwenden, um Pufferüberläufe zu vermeiden.

2. Was ist der Unterschied zwischen fgets() und scanf()?

fgets() liest eine spezifische Menge von Zeichen aus einem Datenstrom, während scanf() verschiedene Datentypen wie Integer, Float und Strings einlesen kann. Für das Einlesen von Strings ist fgets() sicherer, da es Pufferüberläufe vermeidet.

3. Wie kann ich das Newline-Zeichen, das von fgets() gelesen wurde, aus dem Array entfernen?

Sie können die Funktion strtok() verwenden oder, wie im Beispiel oben gezeigt, manuell das letzte Zeichen prüfen und ersetzen.

4. Gibt es eine Alternative zu gets()?

Ja, fgets() ist die empfohlene Alternative zu gets().

5. Was versteht man unter einem Pufferüberlauf?

Ein Pufferüberlauf tritt auf, wenn mehr Daten in einen Puffer geschrieben werden, als dieser fassen kann. Dies kann zu Fehlverhalten, Datenbeschädigung oder Sicherheitslücken führen.

6. Wie lassen sich Pufferüberläufe vermeiden?

Verwenden Sie die Funktion fgets() für Benutzereingaben und überprüfen Sie die Eingabegrößen sorgfältig.

7. Welchen Vorteil bietet fgets() gegenüber gets()?

fgets() ist sicherer und zuverlässiger, da es eine Größenbegrenzung hat und Pufferüberläufe verhindert.

8. Gibt es weitere Funktionen zum Einlesen von Benutzereingaben in C?

Ja, es gibt diverse andere Funktionen wie scanf(), getc() und getchar().

9. Wann sollte scanf() verwendet werden?

scanf() kann zum Einlesen unterschiedlicher Datentypen verwendet werden. Es ist jedoch wichtig, die Formatierungszeichen sorgfältig zu verwenden, um Pufferüberläufe zu vermeiden.

10. Wo finde ich weitere Informationen zu fgets() und gets()?

Die Dokumentation der C-Standardbibliothek bietet detaillierte Informationen zu den Funktionen fgets() und gets(). Zusätzliche Informationen können in Online-Tutorials und Foren gefunden werden.

Schlüsselwörter: fgets, gets, C-Programmierung, Benutzereingabe, Pufferüberlauf, Sicherheit, Dateneingabe, Standard-Eingabe, stdin