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.
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
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
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
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
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
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
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?!
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

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.