Ich lese aus einem String "initFile" eine Zahl, von der ich weiß, wo sie
anfängt ( pos - charCnt ).
Jatzt habe ich folgendes Problem: Wenn im String z.B. 300 steht, dann
wird value_ eine 45 zugewiesen. atoi erzeugt also aus der 300 scheinbar
einen Überlauf, denn 45 ist ja genau die Differenz von einem char zu
300. Aber atoi bedeutet doch ascii to integer? Was passiert hier, und
wie löse ich das?
Mein Programm läuft auf einem MSP430.
Walter schrieb:> cde schrieb:>>> *value_=atoi(initFile+(*pos_)-charCnt);>> Soll das initFile[*pos-charCnt] heissen?>> bestimmt nicht denn was wäre nur ein char
Uuuups, atoi mit was anderem verwechselt...
kleinmachundleisewegschleich
Mark M. schrieb:> wie löse ich das?
Indem du erstmal mehr Information postest.
Wie sieht dein String beispielsweise aus?
Was steht dann in *pos, wenn die Funktion aufgerufen wird?
Und welche Bedeutung hat charCnt? Wie wird es bestimmt?
> void getValue(int *value_, int *pos_)> {> char charCnt;> // Anweisungen
Dein Problem steckt höchst wahrscheinlich genau hier in diesem Bereich,
den du so lapidar mit "Anweisungen" abtust
Na gut. Ich glaube aber nicht, dass charCnt wichtig zum Verständnis ist,
auch wenn ich recht wenig Ahnung habe. Damit wird einfach nur die
Position bestimmt, wo die Zahl anfängt. Ich glaube, dass hat mit dem
Fehler bei atoi nichts zu tun.
Ich merke gerade, dass ich den Schlunz vor atoi weglassen kann, wenn ich
atoi nur initfile+(*pos_) übergebe... :D Aber ich muss ja auch so die
Zeichen bis zum \r\n zählen.
Deine Funktion hat zwar das Zeug für den OCCC, ist aber
überraschenderweise tatsächlich soweit richtig.
Wie sieht der Aufruf auf? Hast du vor dem Aufruf pos einen vernünftigen
Wert gegeben?
pos hat den Wert des Index, an dem die Zahl beginnt. Wenn im String
initFile nur 30 statt 300 steht, dann funktioniert es und value==30.
Und was ist OCCC? Ich weiß, dass man es nicht umständlicher machen
könnte :D
Mark M. schrieb:> pos hat den Wert des Index, an dem die Zahl beginnt. Wenn im String> initFile nur 30 statt 300 steht, dann funktioniert es und value==30.
Hast du irgendwelche Compile-Warnings.
Wie gesagt: Dein Code ist zwar maximal kompliziert, aber nichts desto
trotz soweit richtig, solange der String nicht zu lange ist und char für
den Compiler nicht ein signed Datentyp ist und du die Funktion mit einem
vernünftigen Wert in pos aufrufst.
> Und was ist OCCC? Ich weiß, dass man es nicht umständlicher machen> könnte :D
OCCC = Obfuscated C Code Contest
Ein Wettbewerb, in dem es darum geht, ein Programm möglichst trickreich
und möglichst verschleiert zu schreiben. Sprich: alle Register zu
ziehen.
ZB. ein komplettes Schachprogramm in 145 Zeichen oder so.
Ich weiß zwar nicht, was da beim atoi schief geht.
Aber im Grunde braucht den keiner. Ist hier sowieso kontraproduktiv,
weil du so ein paar mal durch den String läufst. Das können wir besser.
Unter anderem auch mit besseren Fehlerabfragen.
1
#include<ctype.h>
2
3
voidgetValue(int*value_,int*pos_)
4
{
5
char*string=&initFile[*pos_];
6
7
*value_=0;
8
9
// zur ersten Ziffer vortasten
10
while(!isdigit(*string))
11
string++;
12
13
// die Ziffern zu einer Zahl zusammensetzen
14
while(isdigit(*string)){
15
*value_=*value_*10+(*string-'0');
16
string++;
17
}
18
19
// und bis zum Ende des Satzes gehen
20
while(*string&&*string!='\n')
21
string++;
22
23
string++;
24
*pos_=string-initFile;
25
}
Ich weiß, am Anfang ist das nicht leicht. Aber du solltest dich
schnellstens mit Pointern wenigstens soweit anfreunden, dass du damit
Stringverarbeitung machen kannst. Die Sichtweise mit Array und Index
erweist sich da nämlich sehr oft als sehr umständlich. Vor allen Dingen
deshalb weil man eine Hilfsvariable braucht (die Indexvariable), von der
man den Datentyp nicht vernünftig festlegen kann
Anstelle von
for( i = 0; i < strlen(String); ++i )
Zeichen = String[i];
mach was mit Zeichen
ist es einfacher einen Pointer auf ein Zeichen nach dem anderen im
String zeigen zu lassen
while( *String ) // oder while( *String != '\0' )
Zeichen = *String;
String++;
mach was mit Zeichen
}
macht genau das gleiche. Nur brauch ich kein i und ich muss im Vorfeld
auch nicht wissen wie lang der String ist.
Blöde Frage (hab schon 5 Jahre kein C mehr programmiert)
stört sich atoi() nicht an dem \r\n?
Und selbst wenn whitespaces weggeworfen werden, der String geht doch
dahinter weiter. atoi erwartet doch ein normalen Stringabschluss, und
sein initFile geht doch dann in der nächsten Zeile wohl weiter.
Oder bin ich jetzt verkehrt?
U.R. Schmitt schrieb:> atoi erwartet doch ein normalen Stringabschluss, und> sein initFile geht doch dann in der nächsten Zeile wohl weiter.> Oder bin ich jetzt verkehrt?
Aber in der nächsten Zeile steht keine Zahl, sondern erstmal wieder
Buchstaben, und die werden laut
http://www.cppreference.com/wiki/string/c/atoi ignoriert.