Hi Leute, Ich sitz gerade an einem C Projekt und muss dazu sagen, dass ich ein ziemlicher Anfänger in C bin. Das konkrete Problem sieht so aus, dass mein Programm auffordert, verschiedene Werte einzugeben und dann Berechnungen dazu anstellt. wir haben jetzt nach einigen fehlversuchen, bei denen char Variabeln "falsch" eingelesen wurden, festgestellt, dass bei einem scanf befehl auf einen char, zuerst das letzte "Enter" eingelesen wird, das noch von der Bestätigung der letzten Eingabe "im Raum schwebt". Der einzige Lösungansatz, den wir ergoogeln konnten ist, die "Enter" mit getchar() abzufangen und quasi ins Nirvana zu schicken. Aber gibts da keine elegantere Lösung? Wäre sehr froh über eure Hilfe, Grüße Sascha
Am besten den Code zeigen und das OS nennen. Aber allgemein ist <return> auch ein Zeichen - und nicht ausschliesslich , wie man spontan annehmen könnte - irgendein "Kontrollknopf für das System" der Eingaben beendet. Da Ihr, - wie ich ohne den Code nur annehmen kann -, ein einzelnes Zeichen mit scanf lest, gibt das System zwar ein einzelnes Zeichen weiter; es ist zunächst etwas verwirrend, dass <return> noch dazu auch diesen Weitergabe-Vorgang anstösst. Aber das <return->-Zeichen ist immer noch im Buffer und wird daher beim nächsten scanf eines Zeichens, als nächstes weitergegeben.
1 | #include <stdio.h> |
2 | #include <math.h> |
3 | |
4 | int main(){ |
5 | char c; |
6 | int i; |
7 | double A[10]; |
8 | |
9 | do{ |
10 | printf("Summe[+] oder Produkt[*]?\n"); |
11 | scanf("%c", &c); |
12 | /**getchar();**/
|
13 | printf("Startwert Eingeben:\n"); |
14 | scanf(" %lf", &A[0]); |
15 | if(A[0] == 0){ |
16 | printf("Startwert darf nicht Null sein"); |
17 | }
|
18 | else{ |
19 | switch(c){ |
20 | case '+': |
21 | for(i=1;i<=10;i++){ |
22 | A[i] = A[i-1] + A[0]; |
23 | printf("%lf\n", A[i-1]); |
24 | }
|
25 | break; |
26 | case '*': |
27 | for(i=1;i<=10;i++){ |
28 | A[i] = A[i-1] * A[0]; |
29 | printf("%lf\n", A[i-1]); |
30 | }
|
31 | break; |
32 | default:
|
33 | printf("Sie waren zu dumm, die erste Eingabe zu verstehen. Bitte fahren Sie das System herunter und benutzen Sie nie wieder einen PC\n"); |
34 | }
|
35 | }
|
36 | printf("Moechten Sie beenden?\n"); |
37 | /**getchar();**/
|
38 | scanf(" %c", &c); |
39 | getchar(); |
40 | }while(c != 'j'); |
41 | }
|
Also das ist der Code. wir sind jetzt darauf gekommen, dass wir die ersten 2 getchar() nicht mehr brauchen, da wir einfach bei scanf vor der flag eine leerstelle lassen, die dann das return frisst. komischerweise funktioniert es aber andersrum nicht, also mit leerstelle nach der flag. daher muss das letzte getchar auch nach wie vor aktiv bleiben, da unsere variable c ansonsten im nächsten loop direkt wieder mit return belegt werden würde und das programm dann nicht mehr funktioniert.
:
Bearbeitet durch User
Nun. Ich muss da mal grinsen. :-} Das ist, meiner Meinung nach, allenfalls ein "Würgaround", auf den Ihr durch raten gekommen seid, aber keine gedankliche Ableitung aus der Beschreibung von scanf oder getc. (Offen gesagt, ist mir das noch nie begegnet und ich habe es auch nie selbst so gemacht). Als Lehrer würde ich das, ohne eine Erklärung, wie sich das aus der Spezifikation und Implementierung von scanf ergibt, um eine Note abwerten. Ihr habt hier vier Möglichkeiten (abgesehen von Eurer Lösung): 1. Renès Lösung mit getline, wenn Ihr nichts verstehen wollt, sondern nur die Aufgabe lösen. 2. Die Implementierung von getline anschauen - um zu lernen wie das zusammenhängt. Kann zu Punkt 3 oder 4 führen. 3. Versuchen, das Problem korrekt (wie ich meine) mit scanf/flush bzw. dem Terminal-Mode zu lösen - nicht einfach aber lehrreich. 4. Eine eigene, explizit hingeschriebene Lösung mit getc implementieren - nicht einfach, aber lehrreich.
Beitrag #5434301 wurde vom Autor gelöscht.
Sascha schrieb: > Also das ist der Code. wir sind jetzt darauf gekommen, dass wir die > ersten 2 getchar() nicht mehr brauchen, da wir einfach bei scanf vor der > flag eine leerstelle lassen, die dann das return frisst. komischerweise > funktioniert es aber andersrum nicht, also mit leerstelle nach der flag. > daher muss das letzte getchar auch nach wie vor aktiv bleiben, da unsere > variable c ansonsten im nächsten loop direkt wieder mit return belegt > werden würde und das programm dann nicht mehr funktioniert. Schreib vor jedem %c bei scanf ein Leerzeichen (auch bei dem hinter dem do). Vor dem %lf braucht es nicht stehen, da %f automatisch Whitespace überliest.
Theor schrieb: > Als Lehrer würde ich das, ohne eine Erklärung, wie sich das aus der > Spezifikation und Implementierung von scanf ergibt, um eine Note > abwerten. In den Beschreibung zu scanf steht sehr wohl, dass jede Art von Whitespace im Formatstring eben diese überliest. Es spielt keine Rolle ob da eine Leerzeichen steht oder ein \n (oder ein \r oder ein \t). Theor schrieb: > 3. Versuchen, das Problem korrekt (wie ich meine) mit scanf/flush fflush auf stdin ist nicht vom Standard gedeckt.
:
Bearbeitet durch User
Dirk B. schrieb: > Theor schrieb: >> 3. Versuchen, das Problem korrekt (wie ich meine) mit scanf/flush > > fflush auf stdin ist nicht vom Standard gedeckt. Macht bei Input-Streams auch eigentlich wenig Sinn. Ich würde sowas machen wie:
1 | while (getchar() != '\n') |
2 | ;
|
Dann hab ich alles, was in der Zeile noch vielleicht so rumstand, verworfen, egal ob whitspace oder nicht, und ich kann in der nächsten Zeile sauber neu aufsetzen.
Warum nicht so:
1 | #define MAX_LINE_LEN 64 // oder andere Länge
|
2 | ...
|
3 | char buf[MAX_LINE_LEN]; |
4 | |
5 | if (fgets (buf, MAX_LINE_LEN, stdin)) |
6 | {
|
7 | // Verarbeitung
|
8 | }
|
9 | else // EOF |
10 | {
|
11 | // Programm beenden
|
12 | }
|
Wenn man das Ganze in eine hübsche Funktion verpacken will, dann sollte man dafür sorgen, dass der Buffer die Lebenszeit des Aufrufes überlebt (Stichwort: static). (s)scanf() kann eine sinnvolle Funktion zum Parsen von Dateien oder anderen Datenquellen sein. Für das Lesen von stdin ist sie weniger geeignet.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.