while schleife nicht ausführbar



  • Hallo ich habe eine while schleife erstellt die erst aktiviert wird wenn die Taste j betätigt wurde.Das Problem ist,dass ich gar nichts drücken kann und das Programm direkt stoppt ohne die Abfrage zu überprüfe.Woran liegt das ? Quellcode:

    #include <stdio.h>
    #include <conio.h>

    int main()
    {
    int x;
    int y;
    int erg;
    char ja='j';
    //char nein ='n';

        printf("Geben Sie ein Wert für x ein: ");
        fflush(stdin);
        scanf("%i",&x);
        
        
        
        printf("Geben Sie ein Wert für y ein: ");
        fflush(stdin);
        scanf("%i",&y);
        
        
        erg=x+y;
        
        printf("\nErgebnis:%i",erg);
        
        
      printf("Wollen Sie noch ein wert berechnrn drücken sie j");
    
    
    while(ja==getch())
    

    {
    printf("Geben Sie ein Wert für x ein: ");
    fflush(stdin);
    scanf("%i",&x);

         printf("\nGeben Sie ein Wert für y    ein: ");
        fflush(stdin);
        scanf("%i",&y);
        
        
        erg=x+y;
        
        printf("\nErgebnis:%i",erg);
        
     }
     
    }


  • a) Hast du mal mit einem Debugger durchgesteppt? Dann sollte dir sofort klar werden, warum nichts passiert.
    b) Lern mal Code Tags zu verwenden 🙂



  • Das '\n' von der Entertaste bei der Eingabe von y steht noch im Eingabestrom.



  • @Lambodiablogt sagte in while schleife nicht ausführbar:

    fflush(stdin);

    fflush() ist undefiniert für Eingabestreams.



  • Hallo Lambodiablogt!

    Am besten du löscht den Keyboard-Puffer mit einer selbstgebastelten Funktion:
    [code]
    /* -- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -- /
    /

    • This example is distributed in the hope that it will be useful, but
    • WITHOUT ANY WARRANTY; without even the implied warranty of
    • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    • See the GNU General Public License for more details.
    • You should have received a copy of the GNU General Public License along
    • with this program. If not, see http://www.gnu.org/licenses/.
      */

    #include <stdio.h>

    // This two include-files are used by getch()
    #include <termios.h>
    #include <unistd.h>

    // reads from keypress, doesn't echo
    // if getch() is not available from your current compiler
    int getch(){
    struct termios oldt, newt;
    int ch;
    tcgetattr( STDIN_FILENO, &oldt );
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
    return ch;
    }

    // clears the keyboard buffer by deletion of all
    // characters ahead of the newline sign('\n' == Enter)
    // It is a homemade substitute for getch()
    // As example by Linux
    void clear_Keyboardbuffer(void)
    {
    while (getc(stdin) != '\n')
    ;
    }

    int main()
    {
    int x, y, erg;
    char ja='j';
    //char nein ='n';

    printf("\nGeben Sie ein Wert für x ein: ");
    scanf("%i",&x);
    
    printf("Geben Sie ein Wert für y ein: ");
    scanf("%i",&y);
    
    clear_Keyboardbuffer();
      
    erg=x+y;
    printf("\nErgebnis:%i\n",erg);
    

    printf("Wollen Sie noch ein wert berechnen drücken sie j ");
    ja = getch();

    while(ja == 'j')
    {
    printf("\nGeben Sie ein Wert für x ein: ");
    scanf("%i",&x);

    printf("11Geben Sie ein Wert für y ein: ");
    scanf("%i",&y);

    clear_Keyboardbuffer();

    erg=x+y;
    printf("Ergebnis:%i\n",erg);

    printf("Wollen Sie noch ein wert berechnen drücken sie j ");
    ja = getch();
    }

    return 0;
    }

    [/code]

    Sorry, dein Beispiel habe ich ein bisserl umgebaut.
    Wenn du int vor main() nimmst, bitte dann auch mit "return 0;" die Hauptfunktion main abschliessen.
    Früher in DOS-Zeiten hatte der Tastaturpuffer einen fest definierten Speicherbereich. Da dieser
    in DOS noch unverschlüsselt war, konnte man da noch die Speicherbereiche direkt manipulieren.
    Heute muss man zum Beispiel zu solchen selbstgebastelten Funktionen greifen.



  • Sorry da hat sich wohl was geändert:

    /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
    /*
     * This example is distributed in the hope that it will be useful, but
     * WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     * See the GNU General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License along
     * with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    #include <stdio.h>
    
    // This two include-files are used by getch()
    #include <termios.h>
    #include <unistd.h>
    
    // reads from keypress, doesn't echo
    // if getch() is not available from your current compiler
    int getch(){
        struct termios oldt, newt;
        int ch;
        tcgetattr( STDIN_FILENO, &oldt );
        newt = oldt;
        newt.c_lflag &= ~( ICANON | ECHO );
        tcsetattr( STDIN_FILENO, TCSANOW, &newt );
        ch = getchar();
        tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
        return ch;
    }
    
    // clears the keyboard buffer by deletion of all
    // characters ahead of the newline sign('\n' == Enter)
    // It is a homemade substitute for getch()
    // As example by Linux
    void clear_Keyboardbuffer(void)
     {
     while (getc(stdin) != '\n')
        ;
     }
    
    
    int main()
    {
    int x, y, erg;
    char ja='j';
    //char nein ='n';
    
        printf("\nGeben Sie ein Wert für x ein: ");
        scanf("%i",&x);
      
        printf("Geben Sie ein Wert für y ein: ");
        scanf("%i",&y);
    
    	clear_Keyboardbuffer();
          
        erg=x+y;
        printf("\nErgebnis:%i\n",erg);
        
        
      printf("Wollen Sie noch ein wert berechnen drücken sie j ");
      ja = getch();
    	
      while(ja == 'j')
      {
       printf("\nGeben Sie ein Wert für x ein: ");
       scanf("%i",&x);
    
       printf("11Geben Sie ein Wert für y ein: ");
       scanf("%i",&y);
    
       clear_Keyboardbuffer(); 	 
        
       erg=x+y;
       printf("Ergebnis:%i\n",erg);
    
       printf("Wollen Sie noch ein wert berechnen drücken sie j ");	  
       ja = getch();
      }
    
     return 0;	
    }
    


  • Anzmerken ist noch, das für

    return 0;

    auch return EXIT_SUCCESS;
    genommen werden kann, ist in stdlib.h zu finden.
    Ist eine reine Frage des Stils und des Geschmacks.
    Bei oberen Beispiel bitte in Zeile 69 die "11" aus den String entfernen.
    Sonst sollte es funzen.


  • Gesperrt

    @DirkB sagte in while schleife nicht ausführbar:

    Das '\n' von der Entertaste bei der Eingabe von y steht noch im Eingabestrom.

    Dann geht's hier weiter: https://stackoverflow.com/questions/5240789/scanf-leaves-the-new-line-char-in-the-buffer
    ☺



  • Wie wäre es mit:

    printf("Wollen Sie noch ein wert berechnen drücken sie j ");
      	
      while(getch() == 'j')
      {
       printf("\nGeben Sie ein Wert für x ein: ");
       scanf("%i",&x);
    
       printf("Geben Sie ein Wert für y ein: ");
       scanf("%i",&y);
    
       clear_Keyboardbuffer(); 	 
        
       erg=x+y;
       printf("Ergebnis:%i\n",erg);
    
       printf("Wollen Sie noch ein wert berechnen drücken sie j ");	  
      }
    

  • Gesperrt

    @rustyoldguy sagte in while schleife nicht ausführbar:

    printf("Wollen Sie noch ein wert berechnen drücken sie j ");

    OT: Besser: "Wollen Sie noch 1 Wert berechnen ...
    Kleiner Scherz am Rande. 😆
    Nebenbei: ich hasse Programme, die mich siezen.



  • @rustyoldguy sagte in while schleife nicht ausführbar:

    Wenn du int vor main() nimmst, bitte dann auch mit "return 0;" die Hauptfunktion main abschliessen.

    Sinnfrei.

    @rustyoldguy sagte in while schleife nicht ausführbar:

    Anzmerken ist noch, das für
    return 0;
    auch return EXIT_SUCCESS;
    genommen werden kann, ist in stdlib.h zu finden.

    Am Ende von main() ist beides sinnfrei.

    Wäre nett wenn du den Quatsch aus deinem Post entfernen würdest.



  • ein

        int antwort;
        puts("nochmal?");
        scanf(" %c", &antwort);
    while(antwort=='j')
    

    tut es auch.
    Beachte das Leerzeichen vor dem %c



  • @rustyoldguy deine Funktion löscht nicht den Tastaturpuffer.
    Das sollte dann auch mehrere '\n' löschen. Tut es aber nicht.
    Darum ist der Name der Funktion irreführend.



  • also der visual c++ compiler kann fflush(stdin) verarbeiten, steht ganz klar im msdn.
    https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fflush?view=vs-2017



  • @Wade1234 Daß ein Compiler (bzw. dessen Implementierung der Standardbibliothek) von dem bisher in diesem Thread nichteinmal die Rede war für fflush() auf Inputstreams etwas tut, das der Großteil der restlichen Welt anders sieht, ist nicht wirklich ein gutes Argument.


  • Gesperrt

    @Wade1234 sagte in while schleife nicht ausführbar:

    also der visual c++ compiler kann fflush(stdin) verarbeiten, steht ganz klar im msdn.
    https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fflush?view=vs-2017

    Das ist eine MS-Spezialität.

    fflush on input stream is an extension to the C standard

    Bei MS geht auch das:

    for (int i = 0; i < count; i++) 
    {
      // Mach was ..
    }
    printf ("%d\n", i); // i ist hier gültig! 
    


  • @RBS2 sagte in while schleife nicht ausführbar:

    Bei MS geht auch das:

    In welchem Jahr?


  • Gesperrt

    @Swordfish sagte in while schleife nicht ausführbar:

    @RBS2 sagte in while schleife nicht ausführbar:

    Bei MS geht auch das:

    In welchem Jahr?

    Das war bei Visual Studio 2015 noch so.
    MS versteht das wohl als Feature, nicht als Bug.


  • Gesperrt

    @Swordfish sagte in while schleife nicht ausführbar:

    In welchem Jahr?

    Siehe dazu auch:

    Die /Zc: forScope Option ist standardmäßig aktiviert.

    https://docs.microsoft.com/de-de/cpp/build/reference/zc-forscope-force-conformance-in-for-loop-scope?view=vs-2017



  • Von deinem Link im Original:

    Standard behavior is to let a for loop's initializer go out of scope after the for loop. Under /Zc:forScope- [off] and /Ze, the for loop's initializer remains in scope until the local scope ends.

    The /Zc:forScope option is on by default.

    Diese Passage in der Doku ist für 2015 und 2017 genau gleich. Also hat 2015 das mit den Standardeinstellungen sicher nicht erlaubt. Zumal /Zc:forScope- schon in 2015 deprecated war.

    gcc hat bis 2.7 dasselbe gemacht um alten pre-Standard-Code nicht zu brechen.


Anmelden zum Antworten