Wie funktioniert getchar() genau?



  • Folgendes Programm:

    #include <stdio.h>
    
    int main()
    {
      int c;
    
      printf("Programmende mit STRG+D bzw. STRG+C\n");
      while ((c = getchar()) != EOF)
      {
    	  putchar(c);
      }
      return 0;
    }
    

    Mich würde mal interessieren wie getchar genau funktioniert.
    Mir ist da nämlich nicht ganz klar, wie c sein nächstes Zeichen erhält.

    Ich stelle mir die Schritte gerade so vor:
    1. Wenn getchar aufgerufen wird, dann schreibt es so lange Daten in seinen Puffer bis die Enter Taste gedrückt wird.
    2. Wird die Entertaste gedrückt, dann wird das erste Zeichen im Puffer an c übergeben.
    3. Nun wird in die Schleife reingegangen und c mit Putchar im terminal ausgegeben.
    4. Wir sind nun wieder beim Schleifenkopf. C scheint nun das nächste Zeichen aus dem Puffer zu bekommen.

    Aber wieso?
    Getchar wird hier zwar nochmal aufgerufen, aber es scheint selbst die Eingabe im Terminal nicht nochmals aufzurufen, denn der Benutzer muß weder etwas eingeben noch die Entertaste drücken.

    Ich gehe also von Folgenden zwei Bedinung aus:

    A) Ist der Puffer leer, dann erwartet getchar eine Eingabe von der Tastatur mit einem Abschluß mit Enter.

    😎 Ist der Puffer aber noch vom letzten mal voll, dann wird nur das erste Zeichen im Puffer zurückgegeben und die Funktion getchar so gleich wieder verlassen.

    Wenn es diese zwei Zustandsmöglichkeiten A) und 😎 für getchar zutreffen, dann
    ist natürlich klar, warum c beim 2. Durchlauf mit dem nächsten Zeichen gefüttert wird und keine neue Eingabe erwartet wird.
    Erst wenn der Puffer von getchar leer ist, wird von getchar wieder eine neue Eingabe erwartet.

    Ist meine Erklärung bzw. Vorstellung von getchar so richtig?

    Wenn ja, wo speichert getchar dann den Puffer?
    Bzw. wie bleibt der dem Programm erhalten?
    Wenn der Puffer erst in der getchar Funktion angelegt wird, dann müßte dieser ja verloren gehen, sobald getchar verlassen wird.
    Kann es also sein, daß innerhalb von getchar dieser Puffer mit static deklariert wurde?



  • Ich würde mir das ganze so denken:

    +--------------------------------+
    | STDIN                          |
    | -> Gepuffert, wartend auf '\n' |
    +--------------------------------+
    |
    +-> +----------------------------+
        | Queue (first in, first out)|
        +----------------------------+
        |
        +-> +---------------------------------------------------+
            | getchar() fragt bei Queue, sind keine zu lesenden |
            | Zeichen vorhanden blockiert es.                   |
            +---------------------------------------------------+
    

    Bin hier allerdings selbst noch Anfänger und diese Antwort ist somit alles andere als ausführlich. Bin ja sehr gespannt auf die Antworten hier 😃



  • Also
    laut dem ANSI C89 Standard ist getchar dasselbe wie getc(stdin). stdin ist ein "line buffered stream", d.h. die C-Bibliothek hat intern einen Buffer der auf '\n' wartet (das Bild von cooky451 sieht gar nicht schlecht aus). Der Standard gibt nur vor dass ein line-buffered stream (wie stdin) auf irgendeine Weise weitertransportiert wird (z.B. durch ne queue, weiß nit genau wie glibc das macht) wenn \n autaucht oder wenn der buffer voll ist (d.h. dein getchar müsste auch weitergehen wenn die Zeile lang genug is, ich habs aber nicht probiert). Mit setbuf kann man dieses Verhalten ändern(z.B. stdin blockweise puffern (was aber nicht wirklich Sinn macht))



  • Was passiert genau, wenn der Buffer voll wird?

    Muß man dann wieder Enter bzw. \n Eingeben, weil dann getchar Blockiert?

    Wenn ja, welche Funktion sollte man dann zur Eingabe benutzen, wenn so ein Verhalten mit dem Enter drücken unerwünscht ist?



  • C Anfänger schrieb:

    Was passiert genau, wenn der Buffer voll wird?

    Muß man dann wieder Enter bzw. \n Eingeben, weil dann getchar Blockiert?

    Wenn ja, welche Funktion sollte man dann zur Eingabe benutzen, wenn so ein Verhalten mit dem Enter drücken unerwünscht ist?

    Nunja das was passiert wenn der buffer voll ist wird wohl vom OS geregelt.. Vermute mal dass hier dynamisch Speicher zugewiesen wird und man den Puffer mit normalen Zeichen erstmal nicht voll bekommt, und wenn doch wird der Prozess halt gestoppt.

    Die zweite Frage verstehe ich nicht so ganz, wenn du meinst ob es eine C-Funktion gibt mit der man ein Zeichen einlesen kann OHNE dass der Nutzer vorher \n eingeben muss so lautet die Antwort wohl nein. C kann das einfach nicht sehen bzw. darauf zugreifen. Falls du für Windows programmierst würde ich auf getch aus der conio.h verweisen 😉



  • Schau dir mal diese Seite an:
    http://www.google.com/codesearch/p?hl=en#XAzRy8oK4zA/libc/stdio/getchar.c&q=lang:c%20function:getchar&sa=N&cd=1&ct=rc
    Ich habe jedoch keinen Schimmer was drin steht, da mein Browser am Arbeitsplatz die Seite nicht anzeigen kann... 😡



  • Der Buffer kann nicht voll werden, höchstens leer. getchar liest doch daraus und schreibt nicht rein, oder versteh ich hier was nicht?

    Das ganze funktioniert etwa so:
    Aufruf von getchar -> gibt es ein Zeichen im Puffer?
    Wenn ja, gib das zurück und entferne es aus dem Puffer (dh setze den Lesezeiger weiter). Ende.
    Wenn nein, fülle den Puffer durch irgendeine betriebssystemspezifische Funktion (das kann blockieren).
    Hat das geklappt, setze den Lesezeiger auf den Anfang, gib das dortige Zeichen zurück, Ende.
    Hat das nicht geklappt, gib EOF zurück.



  • Wenn das ein Betriebssystemspezifischer Puffer ist, wieso ist der dann am Anfang eines Progamms immer leer?

    Warum kann es nicht passieren, daß er auch mal voll ist wenn man das Programm startet?



  • Getchar schrieb:

    Wenn das ein Betriebssystemspezifischer Puffer ist

    Ist er doch gar nicht. Genau lesen!


Anmelden zum Antworten