Eingabepuffer nach getchar() leeren



  • Hallo !

    Ich hab ein blödes Prob. Ich will eine Datei Zeilenweise ausgeben, wie das tolle unix Programm more. Okay, also will ich auch, dass der User die Ausgabe fortfahren kann, wenn er die Entertaste drückt. Na gut hier kommt mein Code:

    char c;
    int linesToDisplay = 20;
    while( linesToDisplay > 0 && (c = fgetc(file)) != EOF  ) {
        putchar(c);
        if(c == '\n') 
           --linesToDisplay;
        if( linesToDisplay == 0) {
           linesToDisplay = 1;
           getchar();       
        }      
    }
    fclose(file);
    

    Okay, Prob ist wohl offensichtlich. Wenn der User Enter drückt, dann bekomm ich danach einfach nicht das NewLine Zeichen \n aus dem Puffer raus. Hab schon folgendes probiert:
    1.

    if( linesToDisplay == 0) {
    	linesToDisplay = 1;
    	getchar();
        fflush(stdin);
    
    /*zweimal getchar() hintereinander*/ getchar();getchar()
    

    Iss schon doof, aber ich hab's halt mal versucht 😉

    if( linesToDisplay == 0) {
    	linesToDisplay = 1;
    	while(getchar() != '\n');
    
    #include <conio.h>
    /*....program...*/
    if( linesToDisplay == 0) {
    	linesToDisplay = 1;
    	getche();
    

    Fehlermeldung des gcc Compilers. Ich weiss iss kein Ansi, aber gibt's was vergleichbares. Die Methode find ich jedenfalls saugeil.

    Hat leider in keinem Fall eine Wirkung. Wie bekomm ich das NewLineZeichen denn nu aus emm Buffer ??

    Über Antwort würde ich mich sehr freuen.

    mfg
    tom



  • fflush(stdin) ist blödsinn - aber soweit bist du ja auch schon gekommen.

    Weiters: EOF ist kein char sondern ein int - das bedeutet du musst c als int deklarieren.

    Was funktioniert an dem
    while(getchar()!='\n'); denn nicht?

    Ansonsten kannst du den Buffer natürlich auch leeren:

    void clearBuffer()
    {
      setvbuf(stdin, NULL, _IONBF, 0); 
      setvbuf(stdin, NULL, _IOFBF, BUFSIZ); 
      while(getchar() != '\n' ); 
    }
    


  • Hi !

    Es funktioniert leider nicht. Ich erhalte immer noch die flasche Ausgabe. Ich poste mal das Prog. Iss nicht so lang.

    #include <stdio.h> //printf, filehandling etc
    #include <stdlib.h> //exit mehtod
    
    /*This program is comparable to the gnu program more
      It gets an argument, that is a valid filename in
      the system, and displays it's content on the stdout, the screen.
      It is quit, if the user presses the q key*/
    
    int main(int argc, char* argv[]) {
      /*make shure the user passes enough arguments
        to the program. The argument must be a filename that is 
        valid*/
      if(argc < 2) {
        printf("myless <filename>\n"); //tell the user how to use the program
        exit(1); 
    
      } else {
    
        FILE *file = NULL; //FILE creates a new FileHandle
        /*open the file, if this fails tell the user. Note: We ONLY regard the last argument!*/
        if( (file = fopen( argv[argc-1], "r")) == NULL ) {
          printf("File not found.\n");
          exit(1); //quit the prog
        }
    
        char c;  //character stores the read character from file 
        int linesToDisplay = 20; //display the first 20 lines of the file on the screen
    
        while( linesToDisplay > 0 && ((int) (c = fgetc(file))) != EOF  ) {
          putchar(c); 
          if(c == '\n') 
    	    --linesToDisplay;/*every line is terminated by a newline, so if we get one we have just displayed a 
    			    line. Therefore we decrease the number of lines, we still have to put on screen.*/ 
          if( linesToDisplay == 0) {
    	    linesToDisplay = 1; //Display 1 more line, if the user presses Enter
    	    if( getchar() == 'q') {
    	      fclose(file); //close file
              exit(1); //quit if the user gets rid of the file  
            }
            setvbuf(stdin, NULL, _IONBF, 0);  
            setvbuf(stdin, NULL, _IOFBF, BUFSIZ); 
          }
    
        } //end while loop
    
        fclose(file); //close file
    
      } //end else block
    } //end program
    

    Wenn ich jetzt noch while(getchar() != '\n') einbaue, dann werten jedesmal zwei Newlines erzeugt.

    Wieso geht das hier nicht ? Hat jemand eine Idee, würde mich jedenfalls sehr freuen.

    mfg
    tom



  • Ich hab übrigens noch ne Frage. Das Prog iss ne Hausaufgabe. Es soll zusätzlich noch die Anzahl der Zeilen ermittelt werden die derzeit auf dem Bildschirm dargestellt werden können. Halt wie bei More.
    Mit welcher Methode kann man diese Infos bekommen?

    mfg
    tom



  • > dann werten jedesmal zwei Newlines erzeugt
    Es werden keine zwei \n "erzeugt" ... sondern einfach
    zwei ausgegeben!
    das erste mit
    putchar(c);

    und das zweite mit
    getchar()
    welches ja keine "blinde" Eingabe bedeutet sondern auch die
    Benutzereingabe (ENTER) ausgibt.

    Du könntest die Ausgabe aber unterdrücken

    while( linesToDisplay > 0 && ((int) (c = fgetc(file))) != EOF  ) { 
          if(c == '\n')  
            --linesToDisplay;/*every line is terminated by a newline, so if we get one we have just displayed a  
                    line. Therefore we decrease the number of lines, we still have to put on screen.*/  
          if (linesToDisplay > 0)
           putchar(c);     
          if( linesToDisplay == 0) {
    

    Oder eine blinde Eingabe verwenden, aber das gibts glaub nicht
    im Standard (Freaks daher!)?

    Und das Auslesen der Zeilen... geht das überhaupt portierbar ?
    Ich meine unter DOS über den Textmodus geht das doch ganz anders als
    in einer Unix-Konsole?



  • Thx for the tip, geht jetzt. 🙂

    Desweiteren ist die Portierbarkeit uninteressant. Das ganze soll unter Solaris laufen können, that's all.
    Hat da jemand ne Idee?

    mfg
    tom



  • Du koenntest die Ausgabe von stty parsen...
    2. Zeile nach dem "=" 😉



  • Hi Solaris'dUKe!

    Kannst Du mir das mal genauer erklären? 😕 Ich kann mit dem Tip nicht viel anfangen, hab leider nicht so ne mega Ahnung von Unix.:p

    mfg
    tom



  • Naja.. das tool "stty' wuerde dir die Informationen liefern.
    Das dumme ist nur, mir ist nicht bekannt wie stty selber an die
    Anzahl Zeilen kommt.
    Deshalb muesste ich die Ausgabe von stty im Programm verarbeiten.
    (was designmaessig schlecht ist)
    Ruf mal in der Konsole "stty" auf (ohne Parameter). Dann siehst du
    die Anzahl Zeilen in der Ausgabe.
    Wenn du nun also "stty > /tmp/stty.out" aufrufst haettest du nun die
    Datei "tmp/stty.out" mit den entsprechenden Informationen.

    bisher alles klar?



  • Wenn wir schon nichtportabel proggen, dann gleich richtig 😉

    http://www.mcsr.olemiss.edu/cgi-bin/man-cgi?getch+3

    damit koenntest du vermutlich auch eine "blinde" Eingabe
    realisieren...

    Aber eigentlich sollte man das im Unix-Forum weiterbearbeiten...
    denn das ist weit ab von ANSI..



  • cool, vielen Dank für den Tip. 🙂

    mfg
    tom


Anmelden zum Antworten