rekursive Methode: scanf() macht was es will...
-
Hi,
Ich habe ein kleines Programm zu schreiben (Uni) und alle Funktionen laufen.
Alle? Nein. Alle bis auf meine "GUI".
Allgemeines:
-~1700 Postbezirke (Koordinatensystem 2D)
- ich gebe einen Bezirk an und suche den nächsten nachbarn
- ich reise() durch 20 Bezirke (Zufall) und starte bei einem bestimmten..zu meinem Problem:
Ich frage in der rekursiven Methode eingabePruefen(), was der Benutzer eingeben hat bzw. was gemacht werden soll. Und verarbeite die Eingabe über switch().
Beim ersten Aufruf funktioniert noch alles ganz normal:
Die aufgeforderte Funktion wird aufgerufen und verrichtet ihren Dienst.
Über das Break "springts" raus und die Methode ruft sich selber auf.
Dann kommt das was ich nicht so ganz verstehe:
Es überspringt scheinbar die scanf() Funktion und gibt direkt das unter default stehende raus.Was ich aber gar nicht verstehe:
gibt man 'n' ein, so wird eine Funktion aufgerufen, welche auch ein scanf() verwendet. Dort "schalten sich" meine "Sicherungen" (im Sinne von falsche Eingabe) direkt ein (OHNE gewartet zu haben, was der Benutzer denn eingibt) und ich fliege raus (return 0;) Rufe ich die Funktion normal in der main() auf, gibts keine Probleme. Bei reise() und abfragen() nicht.....-.-
Ich finde das Problem nicht....Was muss ich verändern, damit ich sicher gehen kann, dass scanf() auch funktioniert/wartet...?
Danke schonmal
Hier die eingabe Prüfen Methode:
void eingabePruefen(int p){ char ein = '?'; int t = 1; if(p){ p = 0; printf("Ihre Eingabe, bitte: "); }else{ printf("\nBitte waehlen sie erneut: "); } scanf("%c",&ein); // Was hat der User eingegeben? switch(ein){ case 'n': case 'N': if(abfragen() == 0) // Gab es einen Fehler beim Abfragen nach einem Bezirk um den naechsten Nachbar zu finden printf("\nEs gab einen Fehler beim Ermitteln des Startbezirkes."); break; case 'r': case 'R': if(reise() == 0) //"Rundreise" printf("\nEs gab einen Fehler beim Ermitteln des Startbezirkes."); break; case 'e': // Beenden des Programms (algebraischer Bool-Wert [t]) case 'E': printf("Auf Wiedersehen! \n\n"); t = 0; break; case '?': printf("es gibt folgende Programmfunktion:\n"); // Bedienelemente erneut einblenden printf("- 'n': Berechnung der/des naechsten Nachbars/n eines Bezirkes Ihrer Wahl\n"); printf("- 'r': Berechnung einer Route ueber den jeweils naechsten Nachbarn startend mit\n \tdem Bezirk M1_2EA\n"); printf("- 'e': Beenden des Programmes\n"); printf("- '?': Funktionen erneut zeigen\n\n"); break; default: printf("\nIhre Eingabe war leider inkorrekt."); // "falsche" Eingabe } if(t) eingabePruefen(0); }
Dann habe ich noch die abfrage() Funktion, da die reise() Funktion sicher läuft
int abfragen(){ char eingabe[10]; int index = 0; char c = 'e'; printf("Moechten sie den Bezirk nach einem Namen oder einem Index auswaehlen? (N/I)"); scanf("%c",&c); if(c == 'N' || c == 'n'){ // Eingabe nach Name printf("Bitte geben Sie den Namen des Bezirks ein, von welchem der 'naechste Nachbar' gesucht werden soll: "); scanf("%s",&eingabe); int b = 1; // "boolscher" Integer Wert do{ if(strcmp(postbezirke[index], eingabe) == 0 ) // Suche nach dem Index des Bezirkes - strcmp() vergleicht zwei Strings... b = 0; // ...sind sie identisch setzt es den algebraischen Bool-Wert auf "false" -> Schleife bricht ab else index++; }while(b && index < 1726); if(b) return 0; // Bezirk existiert nicht }else if(c == 'I' || c == 'i'){ // Eingabe nach Index printf("Bitte geben Sie den Index des Bezirks ein, von welchem der 'naechste Nachbar' gesucht werden soll: "); scanf("%i", &index); }else{ printf("Ihre Eingabe war inkorrekt."); return 0; } int temp[] = {index}; naechstenNachbarSuchen(1, temp); return 1; }
-
Das Problem ist das die Entertaste auch als Zeichen gilt und eingelesen wird. Schreib also zb.
scanf("%c%c",&c);
, dann wird das "Enter" durch das zweite %c abgefangen.
-
Gnoeg schrieb:
Das Problem ist das die Entertaste auch als Zeichen gilt und eingelesen wird. Schreib also zb.
scanf("%c%c",&c);
, dann wird das "Enter" durch das zweite %c abgefangen.
Das ist falsch. wo soll denn das zweite Zeichen gespeichert werden?
Setze vor das %c noch ein Leerzeichen. Dies veranlasst scanf dazu Whitespace zu überlesen.
scanf("%c",&c);
Die Rekursion der Eingabe ist eine schlechte Idee.
Wenn du nochmal die Eingabe machen willst, dann mach eine Schleife (do-while) darum.Dein Problem mit
abfragen()
konnte ich noch nicht ganz verstehen, liegt evtl aber auch an der Entertaste.
Ein paar Sachen sind mir aber aufgefallen:
Beiscanf("%s",&eingabe);
ist das & zuviel.
Zudem solltest du die Länge des Arrays mit angeben:scanf("%9s",&eingabe);
Was macht eigentlich:
int temp[] = {index};
(Zeile 26 in abfrage)
-
DirkB schrieb:
Das ist falsch. wo soll denn das zweite Zeichen gespeichert werden?
Ich will ja das "Enter" nicht speichern. Es funktioniert, denn wenn scanf zu dem zweiten %c kein Parameter findet, überliest es das zweite Zeichen(das Line Feed) einfach.
-
Quatsch.
scanf weiß zur Laufzeit wegen der variablen Parameterliste nicht, wieviele Argumente du übergeben hast und greift für das zweite %c auf undefinierten Speicher (auch noch schreibend) zu, und das ist undefiniertes Verhalten.
Wenn, dann %c%*c aber auch das ist wie die " %c" Unsinn, da der Anwender einfach 2 Nicht-Whitespaces eingeben kann und dann läuft dein Programm Amok.
Was du 'willst' oder nicht willst, ist dem Compiler egal, der produziert Code, der sich an Regeln hält und dabei wird eben nichts 'überlesen'.
-
DirkB schrieb:
Gnoeg schrieb:
Das Problem ist das die Entertaste auch als Zeichen gilt und eingelesen wird. Schreib also zb.
scanf("%c%c",&c);
, dann wird das "Enter" durch das zweite %c abgefangen.
Das ist falsch. wo soll denn das zweite Zeichen gespeichert werden?
Setze vor das %c noch ein Leerzeichen. Dies veranlasst scanf dazu Whitespace zu überlesen.
scanf("%c",&c);
Die Rekursion der Eingabe ist eine schlechte Idee.
Wenn du nochmal die Eingabe machen willst, dann mach eine Schleife (do-while) darum.Dein Problem mit
abfragen()
konnte ich noch nicht ganz verstehen, liegt evtl aber auch an der Entertaste.
Ein paar Sachen sind mir aber aufgefallen:
Beiscanf("%s",&eingabe);
ist das & zuviel.
Zudem solltest du die Länge des Arrays mit angeben:scanf("%9s",&eingabe);
Was macht eigentlich:
int temp[] = {index};
(Zeile 26 in abfrage)ich habe sie jetzt in eine do-while gepackt:
void eingabePruefen(){ char ein = '?'; printf("Ihre Eingabe, bitte: "); int t = 1; do{ scanf("%c",&ein); // Was hat der User eingegeben? switch(ein){ case 'n': case 'N': if(abfragen() == 0) // Gab es einen Fehler beim Abfragen nach einem Bezirk um den naechsten Nachbar zu finden printf("\nEs gab einen Fehler beim Ermitteln des Startbezirkes."); break; case 'r': case 'R': if(reise() == 0) //"Rundreise" printf("\nEs gab einen Fehler beim Ermitteln des Startbezirkes."); break; case 'e': // Beenden des Programms (algebraischer Bool-Wert [t]) case 'E': printf("Auf Wiedersehen! \n\n"); t = 0; break; case '?': printf("es gibt folgende Programmfunktion:\n"); // Bedienelemente erneut einblenden printf("- 'n': Berechnung der/des naechsten Nachbars/n eines Bezirkes Ihrer Wahl\n"); printf("- 'r': Berechnung einer Route ueber den jeweils naechsten Nachbarn startend mit\n \tdem Bezirk M1_2EA\n"); printf("- 'e': Beenden des Programmes\n"); printf("- '?': Funktionen erneut zeigen\n\n"); break; default: printf("\nIhre Eingabe war leider inkorrekt."); // "falsche" Eingabe } printf("\nBitte waehlen sie erneut: "); }while(t); }
int temp[] = {index};
benutze ich, da ich nur eine Funktion [naechstenNachbarSuchen(int, int[])] haben soll um einmal einen und einmal die "Strecke" zu berechnen. Damit ich es einfacher handhaben kann über gebe ich es bei einem einzelnen ebenfalls als Array.bei abfragen habe ich es jetzt auch so gehandhabt:
scanf("%9s",eingabe);
Mein Problem bei abfragen():
Ich wähle 'n' und drücke Enter. Es erscheint der Code ausprintf("Moechten sie den Bezirk nach einem Namen oder einem Index auswaehlen? (N/I)");
JETZT sollte die Eingabe erfolgen, aber er "überspringt" es und gibt direkt
printf("Ihre Eingabe war inkorrekt.");
aus.
Dann endet die Funktion durch
return 0;
Als nächstes kommt logischerweise der Code von
case 'n': case 'N': if(abfragen() == 0) // Gab es einen Fehler beim Abfragen nach einem Bezirk um den naechsten Nachbar zu finden printf("\nEs gab einen Fehler beim Ermitteln des Startbezirkes."); break;
screenshot:
http://s7.directupload.net/file/d/3049/t48u82ge_png.htm
// ich wusste nicht wie ich einen Anhang hinzufüge .....-.-bei der Eingabe r geschiet dies:
http://s7.directupload.net/file/d/3049/rk77pfx6_png.htmPS: Warum kann/muss ich hier das & bei scanf() weglassen?
Edit: Methode doppelt eingefügt.
-
müll das forum nicht zu -> reduziere die beispiele zu deinen fragen auf ein minimum
-
saubermann schrieb:
müll das forum nicht zu -> reduziere die beispiele zu deinen fragen auf ein minimum
3 Fragen:
Wo sind Beispiele?
Was sollte ich deiner Meinung nach weglassen?
Hast du auch was konstruktives zu dem Thema? [z.B. die/eine Lösung]
-
Hast du das Leerzeichen vor das %c bei scanf gemacht?
Einscanf(" %c",&c);
Überall da, wo du keine Whitespace (Leerzeichen,Tabulatoren und Entertasten) haben willst) einlesen willst?
Und wegen
int temp[] = {index};
solltest du dich mal mehr bei Arrays und Zeigern einlesen.
EinnaechstenNachbarSuchen(1, &index);
tut es da auch.
-
DirkB schrieb:
Hast du das Leerzeichen vor das %c bei scanf gemacht?
Einscanf(" %c",&c);
Überall da, wo du keine Whitespace (Leerzeichen,Tabulatoren und Entertasten) haben willst) einlesen willst?
Und wegen
int temp[] = {index};
solltest du dich mal mehr bei Arrays und Zeigern einlesen.
EinnaechstenNachbarSuchen(1, &index);
tut es da auch.
This is it!
doofes Whitespace^^kleine Rechtfertigung meinerseits:
Ich "komme" Java... Da gibt's sowas 'Kompliziertes' nicht^^ der überliest das einfach immerUnd daher kenne ich das mit dem & auch nicht - also wann ich es brauche und wann nicht...
Ich danke euch