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.
Mittelsscanf(" %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 umscanf
packen.
-
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 3Portadresse 00417 1tes Tastatur-Statusbyte
Portadresse 00418 2tes Tastatur-StatusbyteMan 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.