Falsche Reihenfolge printf() scanf()



  • Hallo zusammen,

    ich habe z.Z. die Aufgabe mich in eclipse einzuarbeiten, allerdings stehe ich jetzt vor dem Problem, dass wenn ich ein Programm mit Eingabe schreibe, das Programm erst auf die Eingabe wartet, bevor es zur Ausgabe kommt...

    Bei diesem Pragramm:

    int main(){
    
      int x=0;
      printf("Hallo!\n");
      scanf("%d", &x);
      printf("%d\n", x);
    
      return 0;
    }
    

    sieht das dann z. B. so aus:

    2
    Hallo
    2
    

    Ich muss also erst einen Wert für x eingeben, bevor das Programm mich begrüßt.
    Woran kann das liegen?

    mfg
    Karl



  • printf schreibt den Kram zunächst nur in den Ausgabepuffer. Wenn du willst, dass der sofort an das dahinterliegende Gerät "gespült" wird, musst du das von Hand machen:

    int main(void){
    
      int x=0;
      printf("Hallo!\n");
      fflush(stdout); /* <-- */
      scanf("%d", &x);
      printf("%d\n", x);
    
      return 0;
    }
    


  • Ah Danke!

    Hatte fflush() schonmal versucht, habs aber an die falsche Stelle geschrieben.
    Muss ich das dann jetzt nach jedem printf() machen, oder geht das irgendwie einfacher?



  • Gibt es eine Einstellung bei eclipse, die das für mich erledigt?



  • Denkbar wäre etwas wie

    void flushed_printf(char const *fmt, ...) {
      va_list l;
      va_start(l, fmt);
      vprintf(fmt, l);
      va_end(l);
      fflush(stdout);
    }
    

    Ansonsten könnte es sein, dass es einen plattformspezifischen Weg gibt, deine Konsole zu anderem Verhalten zu überreden - meistens wird der Konsolenbuffer bei der Ausgabe von \n automatisch geflusht. Auf welchem System entwickelst du das eigentlich?



  • Ich mache das ganze unter Solaris.
    In der "normalen" Konsole funktioniert auch alles so, wie ich das möchte.
    Nur bei der eclipse-konsole brauche ich dann das fflush().

    In der Konfiguration habe ich noch nichts gefunden, wie man das ändern könnte 😞

    Ich soll für Erst-Semester ein How-To für C-Programmierung mit eclipse schreiben. Das muss also ohne Makros funktionieren.

    Hat das denn auf jeden Fall mit der Konsole zu tun, oder kann das auch schon beim kompilieren entschieden werden?

    g karl



  • Hab jetzt

    setvbuf(stdout, 0, _IONBF, 0);
    

    gefunden. Hat den Vorteil, dass ich es nur einmal aufrufen muss.
    Gibt es gravierende Nachteile gegenüber fflush(stdout)?

    g Karl



  • Ah. Eclipse hatte damit in der Vergangenheit schon Probleme, vgl. hier. Ich weiß jetzt nicht, welche Eclipse-Version du benutzt; vielleicht gibt es ja eine neuere, in der das behoben ist (der Bug ist von 2002 und da als behoben markiert).

    Ansonsten könntest du es mit

    setvbuf(stdout, NULL, _IONBF, 0);
    

    versuchen.

    Im Übrigen ist die Funktion, die ich dir geschrieben habe, kein Makro.



  • Nutze eclipse 3.2.0.
    Die Version ist glaube ich von 2006.
    Allerdings kann ich da nichts machen, ist alles Sache der Hochschule.

    Hatte das hier so verstanden, dass va_start etc. makros sind:

    http://www.cplusplus.com/reference/clibrary/cstdarg/

    Naja, so weit gehen unsere Vorlesungen leider nicht 😞

    Danke für deine Hilfe!

    g Karl



  • Nicht immer muss alles der Wahrheit entsprechen, was hier so geschrieben wird.

    Im Zweifel musst du es also selber ausprobieren:

    #include <varargs.h>
    #include <stdio.h>
    
    int main()
    {
    	printf("It is ");
    
    #ifndef va_start
    	printf("not ");
    #endif
    
    	printf("a Macro.\n");
    
    	fflush(stdout);
    
    	return 0;
    }
    


  • va_* sind Makros, das ist richtig (übrigens in stdarg.h; varargs.h wird im Standard nicht erwähnt). Ich hatte das jetzt auf die ganze Funktion bezogen und daran gar nicht gedacht.

    Ich bin nicht sicher, wie sinnvoll es ist, in einem C-Kurs auf fehlerhafte Entwicklungswerkzeuge Rücksicht zu nehmen. Du solltest auf jeden Fall gut dokumentieren, warum das überhaupt da drin steht, und vielleicht mal dem Rechenzentrum auf die Füße treten, dass sie das beheben. Eigentlich ist so was für eine Hochschule kein Zustand.



  • Ich habe mal etwas gegoogelt und es sieht so aus, als würde sich das Problem nicht lösen lassen.

    In einer normalen Konsole würde ein Zeilenumbruch den Puffer automatisch zum Entleeren bringen. Die Sache ist aber die, dass Eclipse die Ausgabe über eine Pipe an ein Konsolenfenster weiterleitet. Dadurch sieht die Konsole keine Notwendigkeit für das Puffern und das von dir beschriebene Verhalten tritt auf.

    Dir bleibt also nichts anderes über als das Programm manuell von einer echten Konsole zu starten, fflush zu verwenden oder setvbuf zu nutzen.

    Wenn du in deinem Tutorial erwähnst, dass der Funktionsaufruf nur aus diesem Grund notwendig ist, dann sollte es da keine Verständnisschwierigkeiten bei deinem Howto geben.

    Its because your program is not launched on a terminal (it uses a pipe), and
    buffered io will only do line buffering if it detects a real terminal (isatty)
    for stdout.

    Quelle: http://dev.eclipse.org/newslists/news.eclipse.tools.cdt/msg01169.html



  • Ok, dann muss ich wohl damit leben.

    Vielen Dank für eure Hilfe!

    g karl


Anmelden zum Antworten