www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik String parsen -> strcmp funktioniert nicht


Autor: Ben M. (benn)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich möchte einen String parsen, der z.B. in der Form "$first=88\r99" 
vorliegen kann. Merkwürdiger Weise kann die nachfolgende Funktion den 
teil zwischen $ und = (hier: "first") sehr gut herausfinden und auch der 
Wert (hier: 88) wird korrekt herausgeparst. Wenn ich tmpstr1 oder 
tmpstr2 in timerbuffer schreibe, erhalte ich den gewünschten Teilstring. 
Es gibt nur ein Problem mit strcmp --> Dort geht er nämlich nicht rein! 
Hat jemand eine Idee, woran das liegen könnte?
void extract_data(char *str)
{
  uint8_t     cnt = 0;
  int8_t      equalspos = -1;
  char       tmpstr1[20];
  char       tmpstr2[20];
  
  if (str[0] == '$') {   // command
    while(str[cnt] != '=' && cnt < strlen(str))
    {
      cnt++;
    }
    if (str[cnt] == '=') {
      equalspos = cnt;
      
      // command
      for (cnt=1; cnt<equalspos; cnt++)
      {
        tmpstr1[cnt-1] = str[cnt];
      }
      tmpstr1[equalspos-1] = '\0';
      
      // value
      cnt=equalspos+1;
      while(str[cnt] != '\r' && cnt < strlen(str))
      {
        tmpstr2[cnt-equalspos-1] = str[cnt];
        cnt++;
      }
      tmpstr2[cnt-equalspos-1] = '\0';
      
      if (newdata == 0) {
        newdata = 1;
        strcpy(timerbuffer, tmpstr1);
      }
      
      
      if(strcmp(tmpstr1, "first") == 0) {
        uart_putc('1');
      }
      if(strcmp(tmpstr1, "second") == 0) {
        uart_putc('2');
      }  
    }
    else {
      
    }
    
  }
  else {          // data
    uart_puts("No Order\r");
  }
}

(Edit: Sorry, dass es in "Mikrocontroller und Elektronik" gelandet ist - 
habe nach der Forensuche nicht mehr darauf geachtet, in welchem Bereich 
ich gerade bin --> würde eher in GCC passen)

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab mir den code nicht ganz genau angeguckt, kenn das Problem aber gut. 
Probier mal strncmp, da du ja eh nur auf "first" und "second" abfragst, 
kannst du einfach fuer "first" die 5, und fuer "second" die 6 Zeichen 
vergleichen. Dann sollte es hinhauen.
      if(strncmp(tmpstr1, "first", 5) == 0) {
        uart_putc('1');
      }
      if(strncmp(tmpstr1, "second", 6) == 0) {
        uart_putc('2');

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also dafür würde ich persönlich strtok() nehmen. Damit lässt sich
ao ein String prima zerlegen (wenn man weiss, wie die Funktion
funktioniert ;-) )

Autor: Helmut Lenzen (helmi1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
while(str[cnt] != '=' && cnt < strlen(str))
{                              ^^^^^^^^^^^  kommt auch nicht gut
      cnt++;                                bei jedem durchlauf wird die
}                                           lange neu berechnet


besser so

while(str[cnt] != '=' && str[cnt] != 0)
{
   cnt++;
}

Gruss Helmi

Autor: Mano Wee (Firma: ---) (manow)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du es so machst wie der Matthias es vorschlägt, mit strncmp(), dann 
muss nicht einmal den String zerlegen!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nichtsdestotrotz ist der Code eigentlich korrekt. Das uart_putc sollte 
aufgerufen werden (und in der Simulation wird es das auch). Daraus 
ergeben sich für mich 3 Möglichkeiten:

1) Der gepostete Code stimmt nicht genau mit dem verwendeten Code 
überein.

2) uart_putc verhält sich unerwartet, so dass es nur so aussieht, als ob 
es nicht aufgerufen wird.

3) Du hast irgendein "globales" Problem, z.B. dass der Stack in den 
Data-Bereich wächst.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
strcmp arbeitet soweit ich weiss bis zum erkennen des String-End 
zeichens \0. Wenn man aber Strings zerpflueckt, geht das \0 dabei unter 
Umstaenden verloren. Moeglicherweise funktioniert der gepostete code 
deswegen ja nicht.

Autor: Ben M. (benn)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die nützlichen Tipps! Es lag scheinbar wirklich an einem 
globalen Problem, so wie es Stefan Ernst auch schon vermutet hatte. 
Nachdem ich einige Funktionen, die ich zum Test eingebaut hatte, 
gelöscht hatte, lief es.

Trotzdem habe ich einige Tipps wie die von Helmut Lenzen und Matthias 
umgesetzt, welche natürlich auch prima funktionieren. Die Idee mit 
strtok() werde ich in Zukunft sicherlich verfolgen, aber da meine 
Parsefunktion momentan gut funktioniert, habe ich das erst mal so 
gelassen.

>> Problem gelöst - vielen Dank!

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.