atoi erzeugt Überlauf?

OP #2030945
Lesenswert?

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.
1
char initFile[SIZE_OF_FILE];
2
int value;
3
int pos;
4

5
void getValue(int *value_, int *pos_)
6
{
7
   char charCnt;
8
   // Anweisungen
9

10
   *value_=atoi(initFile+(*pos_)-charCnt);
11
}
12

13
//Aufruf:
14
getValue(&value,&pos);
#2030977
Lesenswert?

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
OP #2031898
Lesenswert?

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.
1
void getValue(int *value_, int *pos_)
2
{
3
   char charCnt=1;
4
   
5
   while((initFile[*pos_]<'0')||(initFile[*pos_]>'9'))
6
   {
7
      (*pos_)++;
8
   } //finally the first digit was found
9
   (*pos_)++;
10
   while(initFile[*pos_]!='\r')
11
   {
12
      (*pos_)++;
13
      charCnt++;
14
   }
15
   *value_=atoi(initFile+(*pos_)-charCnt);
16
   (*pos_) += 2; //skip "\r\n"
17
}

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.
#2031944
Lesenswert?

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.
#2031966
Lesenswert?

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
void getValue(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.
Gast #2031976
Lesenswert?

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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren