scanf Funktion überspringt die Initialisierung der Variable beim 2. Durchlauf



  • Es soll ein Programm sein, welches die Tastatureingaben mitzählt und in einem Array speichert und dann ausgibt wie oft etwas eingegeben wurde. Allerdings beim Ausführen wird einmal nach Zeichen gefragt, danah beim 2. Durchlauf bei scanf wird einfach 10"\n" zum zeichen und der code läuft weiter.
    Danke für eure Hilfe

    #define NO_SECURE_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    	char zeichen;											
    	int haeufigkeit[128];
    	
    															
    	for (int i = 0; i < 128; i++) {
    		haeufigkeit[i] = 0;
    	}
    
    	do{
    		printf("Gib etwas ein!\n");
    		scanf("%c", &zeichen);
    		
    		if (zeichen > 31 && zeichen < 128) {
    			haeufigkeit[(int)zeichen]++;
    			
    		}
    		
    		
    	} while ((int)zeichen !=  64);
    	
    	for (int i = 0; i < 128; i++) {
    		printf("%d\n", haeufigkeit[i]);
    	}
    	
    }
    

    Ausgabe:
    Gib etwas ein!
    a
    Gib etwas ein!
    Gib etwas ein!
    b
    Gib etwas ein!
    Gib etwas ein!
    a
    Gib etwas ein!
    Gib etwas ein!
    bb
    Gib etwas ein!
    Gib etwas ein!
    Gib etwas ein!
    aa
    Gib etwas ein!
    Gib etwas ein!
    Gib etwas ein!
    @



  • Das Zeilenendezeichen '\n'steht noch im Eingabepuffer.
    Mittels

    scanf(" %c", &zeichen); // beachte das Leerzeichen am Anfang
    

    kannst du Whitespaces (Leerzeichen, Tab, Zeilenende, ...) überlesen.



  • Schreibe bitte in eine Zeile vor Deinem Code ``` und in eine Zeile nach Deinem Code ```. Alternativ markiere Deinen Code und klicke auf das </> in der Symbolleiste über dem Eingabefeld.
    Du kannst Deine Beiträge auch im Nachhinein bearbeiten. Den Menüpunkt "Bearbeiten" findest Du hinter dem Drei-Punkte-Menü rechts unter Deinem Beitrag.
    Danke.


    @furk sagte in scanf Funktion überspringt die Initialisierung der Variable beim 2. Durchlauf:

    haeufigkeit[(int)zeichen]
    

    Darf ich fragen was die Casts - auch an anderer Stelle - bringen sollen?


    @furk sagte in scanf Funktion überspringt die Initialisierung der Variable beim 2. Durchlauf:

    != 64

    Warum schreibst Du nicht '@' hin wenn Du '@' meinst? Vielleicht solltest Du Dir auch mal die Funktionen in <ctype.h> ansehen.



  • @Swordfish in der Aufgabe muss ich nur ASCII Zeichen von 32 bis 127 prüfen wie oft diese eingegeben wurden. Und im Array erhöhe ich dann um 1 wenn beispielsweise 'a' eingegeben wurde dann an Stelle 97 im Array +1



  • @Th69 okay danke dir, ich frag mich aber immer noch wie es dazu kommt, dass wenn ich 2mal ein Zeichen eingebe und dann bestätige die printf anweisung 3 mal ausführt und wenn ich 3mal ein Zeichen eingebe dann wird die printf anweisung 4 mal ausgegeben und immer so weiter...
    Die scnaf Funktion liest irgendwie so oft mein Zeichen nicht ein bis die Schleife einmal mehr durchlaufen ist als ich zeichen eingegeben habe. Dann liest scanf wieder ein.



  • Du liest immer nur genau 1 Zeichen ein, gibst aber in der Schleife jedesmal "Gib etwas ein!\n" aus, so daß dann für jedes Zeichen (inkl. Zeilenendezeichen) dieser Text ausgegeben wird.
    Du solltest die Ausgabe vor die Schleife packen oder eine weitere Schleife um scanfpacken.



  • Du könntest deine Funktion auch so aufbauen:

    initialisiere haeufigkeit;
    while (1 == scanf("%c", &c) && c != '\n') {  
      // solange 1 Zeichen korrekt gelesen wurde und dies kein Enter ist
      if (c == '@') programmende;
      wenn c im interessanten Bereich:
        inkrementiere haeufigkeit für c
    }
    ausgabe haeufigkeiten
    


  • @wob
    Man kann sich auch ne kleine Funktion basteln, die den Tastaturpuffer leer lutscht:

    void clpuf(void)
     {
     while (getc(stdin) != '\n')
        ;
     }
    

    Von mir aus auch clearKeyboardbuffer als Name. Bleibt jeden selber überlassen.



  • Hab noch die cpp-Version vergessen hier zu posten:

    // Loescht Tastaturpuffer cpp-Version
      while (cin.get() != '\n'); 
    

    Für Museumshüter:
    aus Ralph Browns interrupt list:

    DOS 1+ - FLUSH BUFFER AND READ STANDARD INPUT
    
    AH = 0Ch
    AL = STDIN input function to execute after flushing buffer
    other registers as appropriate for the input function
    
    Return:
    As appropriate for the specified input function
    
    Note: If AL is not one of 01h,06h,07h,08h, or 0Ah, the buffer is flushed but no input is attempted 
    

    Der Tastaturpuffer bei DOS:
    0040:0017 Tastenfeldstatus 1
    0040:0018 Tastenfeldstatus 2
    0040:001A-001B Pointer auf Tastaturpuffer Anfang
    0040:001C-004D Pointer auf Tastaturpuffer Ende
    0040:01E Tastenfeld Zwischenspeicher 32Byte
    0040:0096 Tastenfeldstatus 3

    Portadresse 00417 1tes Tastatur-Statusbyte
    Portadresse 00418 2tes Tastatur-Statusbyte

    Man konnte mit Zeiger direkt in den Tastaturpuffer rein. Gott Lob ist das heute nicht mehr möglich!



  • @rustyoldguy sagte in scanf Funktion überspringt die Initialisierung der Variable beim 2. Durchlauf:

    aus Ralph Browns interrupt list:

    Der gute Mensch heißt Ralf mit f. Mit der Liste habe ich mal die Maus unter Turbo Pascal mit Assember angesteuert und dann irgendwann auch lange Dateinamen (nicht mehr nur 8.3, wenn sich jemand an die Einschränkung erinnert) angezeigt 🙂
    Es ging in meinem Code allerdings nicht darum, den Puffer zu leeren. Daher verstehe ich den Zusammenhang zu meinem Posting nicht.



  • @rustyoldguy sagte in scanf Funktion überspringt die Initialisierung der Variable beim 2. Durchlauf:

    Hab noch die cpp-Version vergessen hier zu posten:

    // Loescht Tastaturpuffer cpp-Version
      while (cin.get() != '\n'); 
    
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    

    🙄

    Nein, das ist keine Einladung zu einer Diskussion. Ich weiß nicht was Referenzen zu DOS-Interrupts oder C++ in einem Thread über C auf Linux sinnvoll beitragen sollen. Bitte unterlasse doch in Zukunft solche Off-Topic einwürfe. Ist ja nicht das erste mal.


Anmelden zum Antworten