atoi in Funktionsaufruf
-
Hei Leute, ich dachte mit C könnte mann alles tun was mann machen will.
Warum akzeptiert mir mein Compiler dann kein atoi in nem Funktionsaufruf?
Sieht wie folgt aus:
changeAnswer(atoi(decision), lineNumber);
Danke für eine eventuelle Antwort
Gruss Dani
-
Was ist denn der Fehler den der Compiler liefert?
Wo ist der restliche Code der höchstwahrscheinlich zu deinem nicht genauer spezifizierten Problem führt?
Und auch wenn du die Frage so nicht gestellt hast: Man kann Funktionsaufrufe so schachteln wie du das denkst. Natürlich kann man deshalb noch lange nicht "alles tun was man machen will".
-
hi tim, danke für die schnelle Antwort.
Der Fehler des Compiler ist folgender:
Unbehandelte Ausnahme bei 0x1023f5d6 (msvcr80d.dll) in editTest.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000031.
Die Kopplung zwischen den beiden Funktionen die den Char zurückgibt und ihn dann weiterleitet
char decision; decision = changeAnswerMenu(questionNumber); changeAnswer((atoi(decision)), questionNumber); // param decision: Answer to change
Die Funktion die den Char den ich umwandeln will zurückgibt
char changeAnswerMenu(int questionNumber){ int i; // counter char answer; // setUp Menu // ****************** system("cls"); printTitle(); printQuestionOnly(questionNumber); printf("*******************\n"); printf(" * change Answers\n"); printf("*******************\n"); //******************************** for(i=0;i<testdatas[questionNumber].answercount;i++){ printf("%d. Change answer [ %s ] \n", i+1, testdatas[questionNumber].answers[i]); } if(testdatas[questionNumber].answercount < 5){ printf("%d. Add an answer\n\n", testdatas[questionNumber].answercount+1); } printf("Your choice: "); answer = getchar(); fflush(stdin); return answer; }
Die aufrufende Funktion:
void changeAnswer(int answerNumber, int questionNumber){ printTitle(); if(answerNumber <= testdatas[questionNumber].answercount){ // problem testen // Set up Menu // ************* system("cls"); printTitle(); printQuestionOnly(questionNumber); } }
Und mit alles meinte ich natürlich nicht alles, aber wenn ich zum Teil C-Code sehe, der an Verschachtelungen kaum zu überbieten ist, sollte doch ein atoi auf einen funktionsparameter möglich sein, oder?
gruss dani
-
Das Problem ist, dass man: atoi als Argument nicht ein einzelnes Zeichen sondern einen String erwartet. Wenn du dann nur ein Zeichen übergibst, interpretiert die Funktion den Wert des fälschlicherweise übergebenen Zeichens als Zeiger (Adresse), und eben jenen "Zeiger" zu dereferenzieren crasht dein Programm. Im übrigen ist das keine Fehlermeldung des Compilers, sondern des Programms (genauer gesagt, des Betriebsystems, ausgelöst durch dein Programm). Trotzdem sollte dich der Compiler warnen, dass dein Vorhaben nicht ganz koscher ist. Achte darauf besser
Edit: zu fflush(stdin): http://www.c-plusplus.net/forum/viewtopic.php?t=39349
-
zu fflush:
Uns hat unser lehrer das so beigebracht, als wir mit dem visual studio begannen zu programmieren.
Als wir das noch mit gcc und editplus taten haben wir den tastaturbuffer so gelöscht
do {} while (getchar() != '\n');
Wäre das auch hier angebracht?
grüsse
dani
-
climbaho schrieb:
Wäre das auch hier angebracht?
wäre besser. fflush(stdin) geht nicht überall, getchar() schon. wenn du die getchar-methode nimmst, brauchst du deinen code nicht für jeden compiler umzustricken.
-
Um nochmals auf meine Frage zurückzukommen.
Falls jemand dasselbe Problem haben sollte wie ich:
Folgender Code behebt das oder besser gesagt übergibt der Funktion nicht mehr das einzelne Zeichen sondern die Referenz auf das Zeichen.
So klappt die Umwandlung wunderbar.changeAnswer((atoi(&decision)), questionNumber);
-
&decision zeigt aber nicht auf eine 0-terminierende Zeichenkette, also ist das Verhalten davon undefiniert und könnte genau so gut am Tag darauf (oder an anderen Rechnern) KABUM! machen. Wenn man schon C nimmt, dann sollte man das Hirn schalten und mitdenken, was man da tut.
Möglichkeit 1: (Richtige Verwendung von atoi)
char decision[2]; decision[0] = changeAnswerMenu(questionNumber); decision[1] = 0; changeAnswer((atoi(decision)), questionNumber);
Möglichkeit 2:
changeAnswer(changeAnswerMenu(questionNumber) - '0', questionNumber);
-
Hallo,
silentcatcher schrieb:
Um nochmals auf meine Frage zurückzukommen.
Falls jemand dasselbe Problem haben sollte wie ich:
Folgender Code behebt das oder besser gesagt übergibt der Funktion nicht mehr das einzelne Zeichen sondern die Referenz auf das Zeichen.
So klappt die Umwandlung wunderbar.changeAnswer((atoi(&decision)), questionNumber);
Ist aber immer noch undefiniertes Verhalten, wenn nur:
char decision;
definiert wurde.
MfG,
Probe-Nutzer
-
dann sollte man das Hirn schalten und mitdenken, was man da tut.
Naja... , ohne eingeschaltetes Hirn programmiert wohl niemand, wenn du weisst wie.. bin gespannt.
Zum zweiten: Klar sollte mann grundlegende Kenntnisse darüber haben was eine Funktion macht. Aber für angehende Programmierer wie mich kannst du nicht verlangen dass ich mich monatelang mit printf, atoi, scanf und all diesen anderen Funktionen rumschlage, nur damit ich genau weiss wie und warum die das und dieses so und nicht anders machen.
Seien wir doch ehrlich, als ihr alle zu programmieren angefangen habt und dann ein Programm zum laufen brachtet, habt ihr euch dann wirklich überlegt wieso und warum es geht oder ob sich da noch gefährliche Baustellen verstecken? Solche Sachen lernt mann doch dann wenn man reinfällt oder eben von einem Sachverständigeren aufgeklärt wird.@supertux: Würde das heissen, dass du nie, aber auch gar nie einen einzelnen char definierst, nur weil dieser ja nicht mit 0 terminiert werden kann?
-
Naja... , ohne eingeschaltetes Hirn programmiert wohl niemand, wenn du weisst wie.. bin gespannt.
ooh, hier im Forum findet man immer wieder Bsp dafür.
Womit ich dir Recht gebe, ist dass meine Antwort ein bisschen unpassend ist, bin ich zur Zeit leicht reizbar wegen meiner Prüfung in einer Woche.
climbaho schrieb:
Solche Sachen lernt mann doch dann wenn man reinfällt oder eben von einem Sachverständigeren aufgeklärt wird.
das ist wohl wahr.
climbaho schrieb:
@supertux: Würde das heissen, dass du nie, aber auch gar nie einen einzelnen char definierst, nur weil dieser ja nicht mit 0 terminiert werden kann?
Wenn ich nur einen Wert mit 8 bits speichern will, dann nehme ich (unsigend) char. Wenn ich eine Zeichenkette ein char[] mit genügend Platz für das 0-Zeichen.
-
supertux schrieb:
Womit ich dir Recht gebe, ist dass meine Antwort ein bisschen unpassend ist, bin ich zur Zeit leicht reizbar wegen meiner Prüfung in einer Woche.
Das schaffst du schon, ich drück dir die Daumen.
Und danke für die infos zum einlesen mit char
Grüsse aus zürich
daniel