Anfänger hat Probleme mit scanf aus einem Beispielprogramm



  • Hallo,
    ich bin absoluter Programmieranfänger und versuche mir mit dem älteren Buch C programmieren von Anfang an von Helmut Erlenkötter gerade selber C beizubringen. Bin jetzt gerade bei scanf und das Beispielprogramm will nicht funktionieren! Ich nutze Eclypse Oxygen cdt und wenn ich den Rundlauf Button drücke erscheint gar nichts in dem Konsolen erreichen. Wenn ich trotzdem zwei Zahlen eingebe und mit Enterado bestätige erscheint der Text Rechenprogramm und alle weiteren printf Zeilen mit den richtigen Ergebnissen. Woran kann das liegen? Nach meinem Verständnis müssten doch wenigstens die ersten printf bis zum ersten scanf erscheinen, oder?
    Hier das entsprechende Programm:

    /* bsp10005 */
    #include <stdio.h>
    
    main() {
    int x,y;
    printf("\n\t1 . R e c h e n p r o g r a m m\n");
    printf("\nBitte x eingben :");
    scanf("%i",&x);
    printf("\nBitte y eingben :");
    scanf("%i",&y);
    printf("\n %i + %i ist %i",x,y,x+y);
    printf("\n %i - %i ist %i",x,y,x-y);
    printf("\n %i * %i ist %i",x,y,x*y);
    printf("\n %i / %i ist %i",x,y,x/y);
    printf("\n %i %% %i ist %i",x,y,x%y);
    }
    

    Gruß Heiko

    ~Seppj: Codetags korrigiert.~


  • Mod

    Das ist, wenn ich mich recht erinnere, eine etwas ungewöhnliche (aber nicht verbotene) Eigenart des Eclipseterminals, dass es nicht so oft Text ausgibt, wie das andere Terminalprogramme tun. Wenn etwas mit printf (oder anderen Methoden) ausgegeben wird, dann heißt das nämlich nicht "druck diesen Text auf den Bildschirm), sondern "schreib diesen Text nach stdout". stdout ist die Standardausgabe deines Programms. Das was da rein geschrieben wird, wieder dann wieder von dem Terminalprogramm gelesen und - womöglich nach ein paar mehr Indirektionen dieser Art - dann schließlich irgendwann auf den echten, physischen Bildschirm geschrieben.

    Wann diese Synchronisation stattfindet ist nicht streng vorgegeben. Die meisten Terminalprogramme machen dies bei jedem Zeilenumbruch. Das Eclipseterminal nicht. Man kann aber solch eine Synchronisation erzwingen, indem man

    fflush(stdout);
    

    aufruft. Das macht, dass auf jeden Fall alle bestehenden Zwischenspeicher bis zum Ende weitergegeben werden. Also aller Text, den dein Programm geschrieben hat, landet dann garantiert am Ziel (normalerweise der Bildschirm).

    Wenn du also fflush(stdout) vor jedem scanf machst, dann sollte es funktionieren wie gewünscht, egal welche Art von Terminal benutzt wird. Alternativ solltest du aber auch mal gucken, ob es vielleicht eine Einstellungsoption für das Eclipseterminal gibt, dass es etwas aggressiver flusht.

    PS: Du fragst dich vielleicht: Warum schreiben Terminals Texte nicht aggressiver raus? Die Antwort ist, dass es viel effizienter ist, wenn man möglichst viel Text auf einmal rausschreibt. Jedes einzelne Zeichen stets durch alle Abstraktionsschichten weiter zu reichen, wäre selbst für einen modernen Computer so viel Aufwand, dass es bei vielen Zeichen merklich langsam werden würde. Daher versucht man immer möglichst große Blöcke auf einmal weiter zu geben.



  • Oder du rufst das Programm mit der Konsole von deinem Betriebssystem auf.



  • Dein Buchautor ist als Laie bekannt.
    Benutze hier die C-Codetags, das sollte auch für Anfänger kein Problem sein (für dich aber).
    Kein vernünftiger C-Programmierer benutzt Eclipse zur C-Programmierung, unter Windows nimm den C-Teil aus VStudio2017, sonst KDevelop. Da funktioniert dein Beispielprogramm dann auch; baue eine Schleife ein, die das Ende deines Programm beim 1.Durchlauf aus der IDE heraus verhindert (du siehst dann die Ausgaben nicht, nur bis zum letzten scanf):

    #include <stdio.h> 
    
    int main() { 
    
    do {
    int x,y; 
    printf("\n\t1 . R e c h e n p r o g r a m m\n"); 
    printf("\nBitte x eingben :"); 
    scanf("%i",&x); while(getchar()!='\n');
    printf("\nBitte y eingben :"); 
    scanf("%i",&y); while(getchar()!='\n'); 
    printf("\n %i + %i ist %i",x,y,x+y); 
    printf("\n %i - %i ist %i",x,y,x-y); 
    printf("\n %i * %i ist %i",x,y,x*y); 
    printf("\n %i / %i ist %i",x,y,x/y); 
    printf("\n %i %% %i ist %i",x,y,x%y);
    puts("Ende mit 'j'");
    } while( getchar()!='j' );
    
    return 0; 
    }
    

    https://ideone.com/tk5Odu



  • Super, danke!
    Werde das morgen versuchen umzusetzen 👍
    Ich hatte von VS die 2017er runtergeladen habe da aber keine Konsolenanwendung gefunden 😕 wie gesagt bin blutiger Anfänger.
    Wo lag denn der Fehler bei den codetags?
    Gruß Heiko


  • Mod

    User=0 schrieb:

    Wo lag denn der Fehler bei den codetags?

    Sehen eigentlich richtig aus. Manchmal deaktivieren Leute versehentlich die Unterstützung für BBCode. Das ist eine Einstellung, die es einmal pro Beitrag gibt (unter dem Editfenster "BBCode in diesem Beitrag deaktivieren") und einmal global für das ganze Profil ("BBCode immer aktivieren"). Vielleicht hast du es versehentlich bei einem davon ausgeschaltet.

    edit: Nein, sie sind schlicht falsch. Tags werden mit / geschlossen, nicht mit \. Das macht die Forensoftware auch automatisch für dich, wenn du die Buttons unter dem Editfeld benutzt.



  • Ok, hatte den Schalter für das schließen nicht gefunden und dann wohl den falschen Schrägstrich auf dem Handy gewählt. Gelobe Besserung 🙂
    Gruß Heiko


  • Mod

    Schließen kommt beim zweiten Drücken. Oder Alternativ: Text markieren, dann einmal drücken.



  • Hallo,
    kurze Rückmeldung, habe die Lösung von Witz angewandt und sie funktioniert bei ausführen außerhalb von Eclipse sehr gut.
    Vielen Dank nochmal! Werde sicher noch öfter hier Fragen posten 😃
    Gruß Heiko


  • Mod

    Mit dem erwähnten fflush(stdout) vor scanf wird es wahrscheinlich auch in Eclipse funktionieren.



  • Da hatte Eclipse gemeckert und in Eclipse ging es nicht außerhalb hatte ich nicht mehr getestet.
    Gruß Heiko


Anmelden zum Antworten