Commando aus String suchen..

OP #5150943
Lesenswert?

Halli Hallo,

stehe gerade irgendwie auf dem Schlauch.
Ich möchte gerne ein Kommando aus einem String raus suchen.
Übergeben tue ich der Funktionen einen String und möchte mit einem 
Zeiger Array voller Kommandos vergleichen. Ist ein Kommando mit einem 
aus dem Zeiger Array identisch, soll das übernommen werden. Wenn nicht 
soll weitergesucht werden bis alle Elemente untersucht wurden..

Bekomme es gerade nicht hin :(
1
unsigned int parseString(char str[], parse_t *ParseInfo,  char delimiter)
2
{
3
  #define DELIMITER_BYTE    0
4
  #define FIRST_COMMAND    1
5
  #define SECOND_COMMAND    2
6
  #define BEGINN_RAW_BYTE    3
7
  
8
  #define POSSIBLE_COMMANDO  ( 1<<0 )
9
  unsigned int tempCnt        = 0x00;
10
  unsigned int ptrCnt          = 0x00;
11

12
  
13
  while(*str != delimiter)// pointer to delimiter
14
  {
15
    str++;
16
    if (*str == '\0')
17
    return 1;
18
  }; 
19
  
20
  ParseInfo->receivedCmd[DELIMITER_BYTE] = *str;  
21
  
22
  while(*str)
23
  {
24
    if(*str == *ParseInfo->allowCmd[0])
25
    {
26
      printf("Erfolgreich!");
27
      break;  
28
    }
29
  }
30

31
  return 0;
32
}

delimiter soll der Anfang eines Kommandos darstellen.
#5151148
Lesenswert?

Lass dir doch mal die Zwischenergebnisse von str ausgeben (mit printf 
oder dem Debugger)

Bei printf kannst du die noch zwischen Trennzeichen setzen, damit du 
Leerzeichen besser erkennen kannst.
1
printf("<%s>\n", str);


Nach der ersten while-Schleife zeigt str auf einen delimiter.
Aber damit fangen deine Kommandos sicher nicht an.
Gast #5151211
Lesenswert?

Ich nehme gerne folgendes:
1
#include <string.h>
2

3
char *RX UART_RX_Buffer[0];
4

5
if(strstr(RX, "set") != NULL){
6
    //da seht set im RX: Kommando set ausführen
7
}
Must halt stat "set" einen pointer auf ein Element in deinem Array 
setzen.
strstr liefert einen pointer auf den string zurück, was praktisch ist, 
um damit weiterzuarbeiten.

Vorteil:
Portabel, weil Standarad-C-Funktion, simpel.

Nachteil:
Kein Sparwunder.
Gast #5151280
Lesenswert?

Mmhm schrieb:
> Ich nehme gerne folgendes:

> char *RX UART_RX_Buffer[0];
>
> if(strstr(RX, "set") != NULL){
>     //da seht set im RX: Kommando set ausführen
> }

Normalerweise sind solche RX-Buffer ja als Ringbuffer ausgeführt. Wenn 
ein Teil des Kommandos vor dem Wraparound steht und der Rest dann am 
Anfang des Ringbuffers weitergeht, wird es nicht gefunden. Sieht mir 
also nicht nach einer zuverlässigen Lösung aus.
Gast #5151363
Lesenswert?

1
#include <stdio.h>
2
#include <string.h>
3

4
char *find_cmd(char *str, char del, char *cmds)
5
{
6
    while (*str)
7
        if (*str++ == del)
8
            if (strchr(cmds, *str))
9
                return str;
10
    return 0;
11
}
12

13
int main(int argc, char **argv)
14
{
15
    char *str = ":a:b..:bb..:..:a..:";
16

17
    while (str = find_cmd(str, ':', "ab"))
18
        switch (*str) {
19
            case 'a': printf("Found a\n"); break;
20
            case 'b': printf("Found b\n"); break;
21
        }
22

23
    return 0;
24
}
Gast #5151370
Lesenswert?

Ehm ... die Suche nach dem Begrenzer kann man natürlich auch mit strchr 
machen:
1
char *find_cmd(char *str, char del, char *cmds)
2
{
3
    while (str = strchr(str, del))
4
        if (strchr(cmds, *++str))
5
            return str;
6
    return 0;
7
}
Gast #5151396
Lesenswert?

Nop schrieb:
> Mmhm schrieb:
>> Ich nehme gerne folgendes:
>
>> char *RX UART_RX_Buffer[0];
>>
>> if(strstr(RX, "set") != NULL){
>>     //da seht set im RX: Kommando set ausführen
>> }
>
> Normalerweise sind solche RX-Buffer ja als Ringbuffer ausgeführt. Wenn
> ein Teil des Kommandos vor dem Wraparound steht und der Rest dann am
> Anfang des Ringbuffers weitergeht, wird es nicht gefunden. Sieht mir
> also nicht nach einer zuverlässigen Lösung aus.

Das kommt drauf an, wie man die UART umgesetzt hat, und in welcher 
Umgebung.

Meine Lösung ist halt eben asynchron. Der Emfpang passiert in einer ISR, 
die befüllt den Buffer, wenn das "Stopp-Zeichen" kommt oder der Buffer 
überlaufen würde, wird ein Flag gesetzt. Überschüssige Zeichen werden 
ignoriert, statt vorhanden Daten zu überschreiben.
Die Ausführung des Kommandos passiert komplett asynchron, wenn dem 
Controller grad fad ist. Und das kann auch hunderte ms später sein. 
Danach wird der Buffer gelöscht.
Ich behaupte auch nicht dass das allgemein sinnvoller ist als andere 
Implementierungen oder ein Ringpuffer.
Aber das hier funktioniert auch dann zuverlässig, wenn der Controller 
bei 99,99% Auslastung ist.
Nachteil ist halt die begrenzte Länge einer Message.

Aber sei es wie es sei:
Das Thema war weder um UARTs, noch um Ringpuffer, sondern das finden 
eines Kommandos in einem String. Und das geht fallweise eben auch mit 
strstr.
OP #5151532
Lesenswert?

asdfasd schrieb:
>
1
> #include <stdio.h>
2
> #include <string.h>
3
> 
4
> char *find_cmd(char *str, char del, char *cmds)
5
> {
6
>     while (*str)
7
>         if (*str++ == del)
8
>             if (strchr(cmds, *str))
9
>                 return str;
10
>     return 0;
11
> }
12

13
>

Okay. Das klappt soweit sehr gut. Wie untersuche ich jetzt den 
"Kommando" String nach dem Ende? Habe mir gedacht das ich als 
Kommandoende das '*' Zeichen nehme?!
#5151545
Lesenswert?

mal als Beispiel ein Codeschnipsel
1
      if (Serial.available() > 0) 
2
      { char incomingByte = (char)Serial.read();
3
        if(incomingByte != 13 && incomingByte != 10 )  // Falls nicht Enter kommt muss der Text gespeichert werden in dem inText Array
4
        { if(isprint(incomingByte))
5
          { if(chr_cnt<(MAXBUFFER-2))
6
              serial_in_buff[chr_cnt++] = incomingByte;
7
            else
8
            { Serial.println(F("serBUF ov-> DEL"));
9
              memset(&serial_in_buff[0], 0, sizeof(serial_in_buff)); // 30.554 Bytes
10
              memset(&serial_in_command[0], 0, sizeof(serial_in_command)); // 30.554 Bytes
11
//              *serial_in_command=0;
12
              chr_cnt=0;
13
            } // if(chr_cnt<(MAXBUFFER-1))
14
          } // if(isprint(incomingByte))
15
        } // if(incomingByte != 13)
16
        else // Wenn das Enter ankommt
17
        { serial_in_buff[chr_cnt] = 0;
18
          chr_cnt = 0;
19
          strcpy(serial_in_command, serial_in_buff);
20
          memset(&serial_in_buff[0], 0, sizeof(serial_in_buff)); // 30.554 Bytes
21

22
          if(strlen(serial_in_command))
23
          { Serial.println(F("")); Serial.print(serial_in_command);  Serial.println(F(" -> erkannt")); 
24
                  
25
            if( !strcmp(serial_in_command, "help") || ( !strcmp(serial_in_command, "?") && strlen(serial_in_command)==1 ) )
26
            { // help screen
27
              Serial.println(F("\ncommands: \n"));
28
          
29
              Serial.println(F("hell, hellp, hellm, hellxx(0-10)"));
30
              Serial.println(F("con, conp, conm, conxx(55-75)"));
31
              Serial.println(F("date, dateJJJJ/MO/TA"));
32
              Serial.println(F("time, timeHH:MM:SS"));
33
        
34
              Serial.println(F("up, up?, up07:30"));
35
              Serial.println(F("down"));
36
          
37
              Serial.println(F("stat"));
38
              Serial.println(F("fstat"));
39
              Serial.println(F("i2ceep"));
40
        
41
              Serial.println(F("reset"));
42
              Serial.println(F(""));
43
              memset(&serial_in_command[0], 0, sizeof(serial_in_command));
44
            }
45
        
46
            else if( strstr(serial_in_command, "hell") )
47
            { if( !strcmp(serial_in_command, "hellp") )
48
                backlight_p();
49
              else if( !strcmp(serial_in_command, "hellm") )
50
                backlight_m();
51
              else if( !strncmp(serial_in_command, "hell", 4) && strlen(serial_in_command)>4 && strlen(serial_in_command)<7 )
52
              { // "hell??"
53
                uint8_t tmp_hell = atoi( (char *)serial_in_command + 4);
54
                memset(&serial_in_command[0], 0, sizeof(serial_in_command));
55
                if( tmp_hell>=MIN_BL && tmp_hell<=MAX_BL )
56
                {  MY_EEP_VAR.backlicht = tmp_hell;
57
                   analogWrite(NOK_BL, pgm_read_byte(&pwmtable_11C[MY_EEP_VAR.backlicht])); 
58
                   con_hell_stat(true);  
59
                }
60
                else
61
                { sprintf_P(s_out_str, PSTR("hellxx (%d)-(%d)"), MIN_BL, MAX_BL); Serial.println(s_out_str); // 30.608 Bytes
62
                }
63
              } // if( !strcmp(serial_in_command, "hell??") )
64
              memset(&serial_in_command[0], 0, sizeof(serial_in_command));
65
            } // if( !strcmp(serial_in_command, "hell") )

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren