Einlesen ohne \n - vermeidung von gets()



  • Hallo Zusammen,

    vielleicht eins der einfachsten Probleme wo gibt, aber mich ärgert es schon einige Tage. Wenn ich versuche in einer Schleife Chars oder Strings einzulesen, macht das Programm immer 2 Durchläufe - egal ob ich fgets(input,1,stdin), scanf("%c",&input), input=getc order getchar oder was auch immer verwende.

    einzige Möglichkeit: gets(). Aber: das ist ja evil wegen der fehlenden Längenbeschränkung. Gibt es irgeneinen Trick das mitgelesene Return vor dem nächsten Durchlauf zu eliminieren? Ich habe es schon mit Kombinationen aus fflush() oder \n = \0 ersetzungen versucht, aber vielleicht war ich da nur bei der Reihenfolge falsch.... 😞

    Hier der Beispielcode, der NICHT geht:

    int main(void)
    {
       char x;
        while (x != '0') {
           printf( "Enter a char or '0' to exit: " );
           scanf( "%c", &x );
           printf( "The input was: %c\n\n\n" );
        }
    return 0;
    }
    


  • Für Hilfe bedanke ich mich selbstverständlich schon im Vorraus 🙂



  • Ich verstehe nicht ganz deine Frage. Erstens ärgerst du dich wegen den 2 Durchläufe, dann über das \n Vorkommen. Wie wäre es mit

    size_t len;
    char buffer[1024];
    fgets(buffer, sizeof(buffer), stdin);
    len = strlen(buffer);
    if(buffer[len - 1] == '\n') buffer[len - 1] = 0;
    

    Ansonsten poste doch mal den Code, wobei du 2 Schleifedurchläfe hast.



  • Also, es ging darum, ein simples Hangman-Spiel zu programmieren. Ich lese einen Buchstaben von der Tastatur ein, prüfe auf diverse Sachen und starte die Schleife neu.

    Funktioniert soweit auch, ausser das bei jedem Eingeben von einem Buchstaben gleich 2 Durchläufe angestoßen werden. Einmal korrekterweise mit dem Buchstaben den ich eingeben habe, und einmal mit einer leeren Eingabe, die sich vermutlich auf das abschließende Return (der ersten Eingabe) bezieht.

    Ich habe vermutet, das da einfach noch das "\n" im Puffer hängt und dann beim nächsten Durchlauf verwendet wird und versucht nach der Eingabe mit fflush(stdin) den Puffer zu leeren. Gerade allerdings hab ich dazu gelesen, das dieser Vorgang unter Linux nicht wirklich Abhilfe schafft - Meine Testsysteme waren AIX und eben Linux.

    Laut der Dokumentation liest fgets(), weil es ja für Dateien, die ja durchaus mehrere Zeilen beinhalten können 😉 , is, auch das abschließende '\n' mit ein - im Unterschied zu gets(). Ich hatte gehofft das die anderen Einlesefunktion (getc, getchar, scanf) ähnlich wie gets() funktionieren würden, aber scheinbar ist das doch nicht der Fall. Einen Versuch mit dem Ersetzen des '\n' wie in deinem Beispiel hatte ich auch schon hinter mir, aber vielleicht war da ein logischer Fehler drin, denn dein Code geht.



  • Hans Wurst Noob schrieb:

    Ich habe vermutet, das da einfach noch das "\n" im Puffer hängt

    gut möglich (ohne Code kann ich nur raten). Siehe meinen letzten Post.



  • Hans Wurst Noob schrieb:

    Hier der Beispielcode, der NICHT geht:

    int main(void)
    {
       char x;
        while (x != '0') {
           printf( "Enter a char or '0' to exit: " );
           scanf( "%c", &x );
           printf( "The input was: %c\n\n\n" );
        }
    return 0;
    }
    

    probier mal so:

    #include <stdio.h>
    
    void drain_stdin (void)
    {
      int c;
      do 
      {
        c = fgetc(stdin);
      } while (c != EOF && c != '\n');
    }
    
    int main(void)
    {
      char x = 1;
      while (x != '0') 
      {
        printf( "Enter a char or '0' to exit: " );
        scanf( "%c", &x );
        drain_stdin();
        printf( "The input was: %c\n\n\n", x);
     }
     return 0;
    }
    

    🙂



  • Danke, auch diese Möglichkeit funktioniert so wie sie soll, etwas eleganter wenn man öfter Eingaben so abfangen muss, allerdings wirkt das ganze auf mich eher wie ein Workaround für den Ansi Standard als eine wünschenswerte Lösung.

    Mit gets() würde es ja auch ohne so eine Aufsammelmethode funktionieren....

    Trotzdem danke für eure Mühen...



  • zefix ...

    Du programmierst in C, also muß der PC das machen was Du willst und nichts
    anderes. Du brauchst da neben einigen Kenntnissen (kann man lernen, no prob)
    vielleicht eher etwas mehr Selbstvertrauen.

    Wenn mann ernsthaft in C programmiert (und damit die Karre halt auch voll
    ausfahren kann oder können will) riskiert man halt mal 'nen Reboot.

    Na und ???

    Trau Dich !


Anmelden zum Antworten