mikrocontroller.net

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


Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, Verdauungsbierchen und ich mach mich an Pointer ran.

Vielen Dank erstmal und schönen Abend noch!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.