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


von Ben M. (benn)


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?
1
void extract_data(char *str)
2
{
3
  uint8_t     cnt = 0;
4
  int8_t      equalspos = -1;
5
  char       tmpstr1[20];
6
  char       tmpstr2[20];
7
  
8
  if (str[0] == '$') {   // command
9
    while(str[cnt] != '=' && cnt < strlen(str))
10
    {
11
      cnt++;
12
    }
13
    if (str[cnt] == '=') {
14
      equalspos = cnt;
15
      
16
      // command
17
      for (cnt=1; cnt<equalspos; cnt++)
18
      {
19
        tmpstr1[cnt-1] = str[cnt];
20
      }
21
      tmpstr1[equalspos-1] = '\0';
22
      
23
      // value
24
      cnt=equalspos+1;
25
      while(str[cnt] != '\r' && cnt < strlen(str))
26
      {
27
        tmpstr2[cnt-equalspos-1] = str[cnt];
28
        cnt++;
29
      }
30
      tmpstr2[cnt-equalspos-1] = '\0';
31
      
32
      if (newdata == 0) {
33
        newdata = 1;
34
        strcpy(timerbuffer, tmpstr1);
35
      }
36
      
37
      
38
      if(strcmp(tmpstr1, "first") == 0) {
39
        uart_putc('1');
40
      }
41
      if(strcmp(tmpstr1, "second") == 0) {
42
        uart_putc('2');
43
      }  
44
    }
45
    else {
46
      
47
    }
48
    
49
  }
50
  else {          // data
51
    uart_puts("No Order\r");
52
  }
53
}

(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)

von Matthias (Gast)


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.
1
      if(strncmp(tmpstr1, "first", 5) == 0) {
2
        uart_putc('1');
3
      }
4
      if(strncmp(tmpstr1, "second", 6) == 0) {
5
        uart_putc('2');

von Matthias (Gast)


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 ;-) )

von Helmut L. (helmi1)


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

von Mano W. (Firma: ---) (manow)


Lesenswert?

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

von Stefan E. (sternst)


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.

von Matthias (Gast)


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.

von Ben M. (benn)


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!

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.