mikrocontroller.net

Forum: Compiler & IDEs atoi verrechnet sich aber warum?


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

hab da ein kleines Problem mit der Funktion "atoi".

Der Code soll aus meinen Nachrichten ein Command und einen wert 
interpretieren. Das Command wird immer perfekt kopiert. Der Wert wird 
imemr perfekt kopiert aber die letzten 3 Zeilen sind die wichtigsten. 
Sobald ich den Wert umwandele klappt es beim ersten mal danach kommt nur 
noch mist. Dachte immer atoi kann Zeichen in max 16Bit werte umwandeln.

Habe folgenden Code:

void command()
{
  char fifo[15] = "";      //copyed command
  uint8_t pfifo = 0;    //current fifo point
  char command[10];    //command
  uint8_t pcommand = 0;  //current command point
  char value[5] = "!!!!!";//value as Charakters
  uint8_t pvalue = 0;    //current value point
  uint16_t val = 0;    //value
  bool ok = false;        //OK FLAG

  char buffer[5];
  char massage[20];

  //Reset Command found Flag
  uart.comm_found = false;

  //Read and Write Pointer equal?
  if(uart.rx.pread == uart.rx.pwrite)
    return false;

  //Copy Command from RX Fifo
  do
  {
    fifo[pfifo] = uart.rx_buffer[uart.rx.pread];
    uart.rx_buffer[uart.rx.pread] = '!';


    uart.rx.pread++;
    pfifo++;
    uart.rx.used_size--;

    if(uart.rx.pread >= uart.rx.size)
      uart.rx.pread = 0;

    if(pfifo > 15)
      return false;

  }
  while(uart.rx_buffer[uart.rx.pread] != '#');

  //copy and delete the last '#'
  fifo[pfifo] = uart.rx_buffer[uart.rx.pread];
  uart.rx_buffer[uart.rx.pread] = '!';
  uart.rx.pread++;

  if(uart.rx.pread >= uart.rx.size)
    uart.rx.pread = 0;

  //Copy Command from Fifo
  pfifo = 0;
  while(fifo[pfifo] != '=')
  {
    command[pcommand] = fifo[pfifo];

    pcommand++;
    pfifo++;

    if(pcommand > 10)
      return false;
  }

  command[pcommand] = '\0';

  //Jump over '='
  pfifo++;

  //Copy Value from Fifo
  while(fifo[pfifo] != '#')
  {
    value[pvalue] = fifo[pfifo];

    pvalue++;
    pfifo++;

    if(pvalue > 5)
      return false;
  }

  //Clean Value
  while(value[4] == '!')
  {
    value[4] = value[3];
    value[3] = value[2];
    value[2] = value[1];
    value[1] = value[0];
    value[0] = ' ';
  }


  send_uart(", ");

  val = atoi(value);

  itoa(val,buffer,10);
  send_uart(buffer);
}

Jemand eine Idee?

Autor: Axel Ro. (axelroro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ohne das Programm jetzt genauer analysiert zu haben: Die Falle ist oft, 
dass man einen uint Wert an itoa verfüttert, dieser den aber als signed 
int verarbeitet. Mag also sein, dass atoi noch funktioniert, aber die 
darauffolgende Ausgabe von itoa schief geht. Ggfs dafür utoa nehmen.

Ohne Gewähr - bin auch nicht so der Experte.

Gruss
Axel

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort aber wenn ich nee if anweisung drangäng 
um bei einem bestimten wert etwas zu machen klappt es auch nicht. Die 
umwandlung mit itoa past eigentlich ziemlich gut.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So

mir ist noch was aufgefallen scheinbar scheint er die vorigen werte zu 
behalten warum auch immer. Sende ich zb. relay=1# was das relay anziehen 
lassen soll dann ist der wert denn ich zurück bekomme 1 also stimmt ja.

Sende ich dann relay=2# dann bekomme uch den wert 21 zurück. Sende ich 
relay=5# dann bekomme ich 521 zurück. schon komisch sende ich relay=0# 
dann ändert sich nichts und ich bekomme den alten wert wieder also 521.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast das abschliessende 0-Byte vergessen.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok hab den fehler gefunden.

Bei atoi müssen die anderen Zeichen alle " " blanks sein damit es geht. 
Hatte bevor ich den Code hier gepostet hatte immer eine 0 davor gemacht.

Aber warum findet man die Fehler immer so schnell wenn man hier ein 
Beitrag auf gemacht hat. Hab gestern 2 Stunden daran rum probiert ohne 
erfolg.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:
> while(fifo[pfifo] != '#')
>   {
>     value[pvalue] = fifo[pfifo];
>
>     pvalue++;
>     pfifo++;
>
>     if(pvalue > 5)
>       return false;
>   }

lösch mal pvalue vor dieser Schleife (also nullsetzen).
Das könnte auf das beschriebene Verhalten führen.

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hatte ich auch eben erst gedacht, ob pvalue ist in der Funktion privat 
und diese wird nur einmal durchlaufen. Beim starten wird es ja null 
gesetzt.

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

Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:

> Jemand eine Idee?

Ja.

Punkt 1
   Wenn du Schwierigkeiten hast, weil du nicht weißt, was in einer
   Variablen drinnensteht, dann musst du dir Einblick in die Variable
   verschaffen. Das kann sein ein Debugger, das kann aber auch sein
   dass man sich ganz einfach ein paar Ausgabeanweisungen kurzfristig
   einbaut, die einem zeigen was Sache ist
   In deinem Fall möchtest du gerne wissen, was in value drinnen
   steht.
   Na dann mach dir doch eine send_uart( value) und schau nach was
   drinnen steht!

Punkt 2
   Deine Funktion macht viel zu viel!
   Wenn du einen Fifo hast, dann bau dir Funktionen, die sich um die
   Fifo Verwaltung kümmern. Nicht mehr!
   Aufbauend auf diesen Funktionen baust du dann weitere Funktionen
   auf, die zb einen String aus dem Fifo rauskopieren. Funktionen die
   Einzelteile aus dem String extrahieren etc. Lauter Dinge, die du
   einzeln testen kannst (indem du dir zb das Ergebnis über UART
   ausgeben lässt)
   Und erst dann, wenn du einen entsprechenden Baukasten hast, setzt
   du mit diesen Funktionen deinen Command Line Parser zusammen.

Punkt 3
   Kauf dir ein C Buch. Lerne wie String Verarbeitung in C funktioniert
   und welche Funktionen du fix&fertig zur Verfügung hast und setze
   sie auch ein!

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Punkt 4
•Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Und Code Tags verwenden ;)

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:
> Aber warum findet man die Fehler immer so schnell wenn man hier ein
> Beitrag auf gemacht hat. Hab gestern 2 Stunden daran rum probiert ohne
> erfolg.

Hi, Daniel,

„Eine gute wissenschaftliche Theorie sollte einer Bardame erklärbar 
sein.“ (Ernest Rutherford)

Gelegentlich hilft es schon, wenn ich mein Problem für meine Bardame 
formuliere :-).

Im Rückblick - wenn ich mich abgemüht habe mit eigentlich simplen 
Problemen, war nicht das Problem das Problem, sondern ein Denkfehler.
Banal, nicht wahr? Genauer gesagt, ein Fehler in der Suchstrategie.

Ärzte sollen davon auch nicht ganz frei sein.

Ciao
Wolfgang Horn

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.