Forum: Mikrocontroller und Digitale Elektronik Aus Ascii mach Integer mach Ascii gleich Null??


von Stephan R. (Gast)


Lesenswert?

Moin!

Folgender kleiner Aufbau:

Die Daten eines GPS- Empfängers werden vom Atmega8 empfangen und zu 
einem String zusammengeflickt.

Anschließend wird der String zerpflückt und Teile daraus in Integer 
umgewandelt, damit der uC z.B. Geschwindigkeit besser (/überhaupt) 
handlen kann.

Um zu kontrollieren, ob das klappt, wandle ich diesen Integer wiederum 
in einen String um, um ihn per Terminal auslesen zu können.
Da kommt aber immer wieder 0 bei raus!
Wo steckt der Fehler?

Bereinigter Code:

int wert;                 //späterer Repräsentant für den String- Wert
char Line[3];             //von GPS gefütterter String
wert= atoi(Line[1]);      //interessant ist erstmal nur ein Buchstabe
itoa (wert, ascii, 10);    //zurückwandlen in Terminal- lesbaren Wert
uart_puts (ascii);        //über COM den Wert von Line[1] erhalten 
wollen

ERGEBNIS: 0

von Klaus W. (mfgkw)


Lesenswert?

atoi() benötigt nicht ein char, sondern einen char*.

Bei dir wird das Zeichen genommen, als Adresse interpretiert und der 
dort beginnende String ausgewertet.

Sei froh, daß nur 0 rauskommt.

von Karl H. (kbuchegg)


Lesenswert?

Stephan R. schrieb:

> Wo steckt der Fehler?

Kann man so nicht sagen.

Hast du kontrolliert ob

a)
> Die Daten eines GPS- Empfängers werden vom Atmega8 empfangen und zu
> einem String zusammengeflickt.

Du hier den korrekten String hast

b)
> Anschließend wird der String zerpflückt
du hier die Einzelteile richtig 'zerpflückt' hast


>
> Bereinigter Code:
>
> int wert;                 //späterer Repräsentant für den String- Wert
> char Line[3];             //von GPS gefütterter String
> wert= atoi(Line[1]);      //interessant ist erstmal nur ein Buchstabe

Buchstabe? Welcher Buchstabe? Und warum line[1]?
Entweder in Line ist eine (maximal 2-stellige) Zahl in Textform, oder 
sie ist nicht dort.
Wenn da ein Buchstabe drinnen ist, was soll dann atoi daraus machen? :-)

Aber kontrollier erst mal die ersten beiden Punkte

Und das nächste mal bitte deinen richtigen Code.
Ein
  char Line[3];
stinkt schon mal nach einem Fehler (Array zu kurz)

von Vlad T. (vlad_tepesch)


Lesenswert?

hast du dir mal die zwischenergebnisse angeschaut? zb mit printf oder im 
simulator?

Vorausgesetzt asci ist ein char-Array mit größe >=10 sollte es stimmen.

von Vlad T. (vlad_tepesch)


Lesenswert?

Klaus Wachtler schrieb:
> atoi() benötigt nicht ein char, sondern einen char*.

oh, tatsache, den hab ich auch übersehen.

edit:
das muss heißen
wert = atoi(line);

Wo ein string (pointer auf character-Array) erwartet wird, kannst ud 
nicht einfach ein char  übergeben.

von Stephan R. (Gast)


Lesenswert?

Der String wird völlig korrekt empfangen, das sehe ich daran, dass ich 
den gesamten String via Terminal anzeigen lasse.

Hier nochmals mein mangelhafter Code:

char Line[70];                                    //GPS- Telegramm
int i = 0;
int reihe = 5;
int wert = 0;

while(1)
{
  uart_gets (Line, sizeof (Line));
  for (i = 0; i < 70; i++)          //String auf Terminal-Bildschirm
  {
  cursor_pos ( reihe , i );         //Cursor ein weiter
  uart_putc (Line[i]);              //nächster char
  }

  wert= atoi(Line[7]);               //Line[7] wird geintegert
  char ascii [3];         //Sting für itoa
  itoa (wert, ascii, 10);       //wert wird geasciit
  cursor_pos( 20 , 20);       //an Position 20/20
  uart_puts (ascii);       //ausgeben
}

Ich gab falsch an, der String bereits zerstückelt ist. Dass ich der 
Variable wert nur Line[7] zuzuordnen versuche, ist meine Zerstückelung.
Geht das?

von Vlad T. (vlad_tepesch)


Lesenswert?

Stephan R. schrieb:
> wert= atoi(Line[7]);               //Line[7] wird geintegert

das ist nach wie vor falsch.
erwartet wird ein pointer und du gibtst ihm irgendwas

von Stephan R. (Gast)


Lesenswert?

Wollte, bevor ich mich an Pointer wage, erst noch den gesamten Code 
nachholen.

Wie sähe denn der Pointer aus, der der atoi-Funktion sagt, dass sie z.B. 
aus den drei characters von Line[7] bis Line[9] ein Integer machen soll?

von Karl H. (kbuchegg)


Lesenswert?

Stephan R. schrieb:

> char Line[70];                                    //GPS- Telegramm
> int i = 0;
> int reihe = 5;
> int wert = 0;
>
> while(1)
> {
>   uart_gets (Line, sizeof (Line));


>   for (i = 0; i < 70; i++)          //String auf Terminal-Bildschirm
>   {
>   cursor_pos ( reihe , i );         //Cursor ein weiter
>   uart_putc (Line[i]);              //nächster char
>   }

warum nimmst du hier nucht uart_puts?
dann würdest du auch sehen, ob dein empfangener 'String' auch wirklich 
ein String ist, sprich korrekt 0-Terminiert wurde

>
>   wert= atoi(Line[7]);               //Line[7] wird geintegert

Hatten wir schon: Nein.
Das geht so nicht

atoi will einen String haben. Line[7] ist kein String. Line[7] ist ein 
einzelner Character.

>   char ascii [3];         //Sting für itoa

gewöhn dir für solche Sachen an: lieber klotzen als kleckern. Ein 
char-Array der Länge 3 hat man ganz schnell überlaufen.

>   itoa (wert, ascii, 10);       //wert wird geasciit
>   cursor_pos( 20 , 20);       //an Position 20/20
>   uart_puts (ascii);       //ausgeben
> }

Alles in allem:
Dein SChritt

Den String in Einzelteile zerpflücken ist fehlerhaft, bzw. gar nicht 
vorhanden.

>
> Ich gab falsch an, der String bereits zerstückelt ist. Dass ich der
> Variable wert nur Line[7] zuzuordnen versuche, ist meine Zerstückelung.
> Geht das?

Nein.

2 Probleme
a) du übergibst ein einzelnes Zeichen, wo eine Adresse eines
   Stringanfangs erwartet wird.

   Das könnte man noch beheben

   wert = atoi( &Line[7] );

b) woher weißt du, dass die Zahl immer an Position 7 im String anfängt?
   Bei der ersten Zahl geht das ja noch, aber bei den weiteren Zahlen
   in einem NMEA String ist das nicht mehr so

   Du musst:
     im String nach dem ersten ',' suchen. Gleich dahinter beginnt
     die erste Zahl
     usw. usw.
     d.h. der komplette String wird in Enizelteile zerlegt, indem man
     nach den ',' als Trennstellen sucht und sich dann von dort den
     jeweils nächsten Teil (bis zum darauffolgenden ',') herausholt.

von Karl H. (kbuchegg)


Lesenswert?

Stephan R. schrieb:
> Wollte, bevor ich mich an Pointer wage, erst noch den gesamten Code
> nachholen.

Stringverarbeitung geht nicht ohne Pointer.

> Wie sähe denn der Pointer aus, der der atoi-Funktion sagt,
> dass sie z.B. aus den drei characters von Line[7] bis Line[9]
> ein Integer machen soll?

atoi hört sowieso auf, wenn es auf ein Zeichen stösst welches nicht mehr 
zur Zahl gehören kann.

atoi will einen Pointer auf den Anfang des Strings, bei dem die Zahl 
beginnt.

Bei dir ist das: die Adresse von Line[7]

"Adresse von" schreibt sich in C als &

Also:

    atoi( &Line[7] );


Kauf dir ein C-Buch und arbeite auf dem PC die ersten Kapitel durch. So 
hat das noch wenig Sinn, wenn du dich auf einem AVR mit seinen 
beschränkten Debugmöglichkeiten ohne Vorkentnisse in String-Verarbeitung 
wagst.

von Stephan R. (Gast)


Lesenswert?

Okay, Verdauungsbierchen und ich mach mich an Pointer ran.

Vielen Dank erstmal und schönen Abend noch!

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
Noch kein Account? Hier anmelden.