www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik String für Auswertung Trennen


Autor: µC-noob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich steh mal wieder vor einem Problem, bei dem bisher jeder meiner 
Lösungsversuche gescheitert ist,....

Über den UART empfange ich Daten, die ausgewertet werden müssen:

IMMER dieser Art

">:SET?2\r\n"
">:RESET?2\r\n"
">:TOGGLE?2?1000\r\n

In einer Routine lese ich diese Zeichen nun charweise in einen Buffer 
ein, bis das \r
oder \n erkannt wird, danach möchte ich den string auswerten.

beispielsweise das hier
">:TOGGLE?2?1000\r\n

Soll nachher zu
str1 = ">:TOGGLE"
str2 = 2
str3 = 1000
konvertiert werden

Ihr seht, es gibt ein Kommando eingeleitet mit eiem ">:"
Danach folgen Eingaben, eingeleitet mit einem "?", jedem Fragezeichen 
folgt eine neue Zahl, bis das \r\n kommt, was das Ende des kommandos 
anzeigt.

Gibt es da Bibliotheksfunktionen, oder wie Trenne ich den String am 
besten??

Danke und Gruß
Joe

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

Bewertung
0 lesenswert
nicht lesenswert
Schau dir strtok() an. Mit dieser Funktion ist das nicht
weiter problematisch.

Autor: µC-noob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
danke erstmal,

strtok, gibt es in meiner Bibliothek nicht,
aber dafür strtok_r

Folgendes Programm steht:
struct getCmd_t
{
  char  cmd[20];
  char  Par1[20];
  char  Par2[20];
  char  Par3[20];
};

void splitCommand(void) //(char *rxBuffer)
{
  struct getCmd_t actCommand;

  char *testString =  ">:trigger?2?1000\0"; //">:spcSet?2?R?25?7?R\0";
  char *token;
  char *tmp;

  token = strtok_r( testString, ">:?", &tmp );
  strcpy( actCommand.cmd, token );

  token = strtok_r( NULL, "?", &tmp ); 
  strcpy( actCommand.Par1, token );

  token = strtok_r( NULL, "?", &tmp );
  strcpy( actCommand.Par2, token );

  token = strtok_r( NULL, "?", &tmp );
  strcpy( actCommand.Par3, token );

  add_menutext(&LCDLine1[0], actCommand.cmd, 0);
  add_menutext(&LCDLine2[0], actCommand.Par1, 0);
  add_menutext(&LCDLine3[0], actCommand.Par2, 0);
  add_menutext(&LCDLine4[0], actCommand.Par3, 0); 
}

Mein Problem,
ich möchte dieses Dynamisch gestalten, so dass nicht auf fest vier 
Parameter geteilt wird, sondern bis zum Stringende.
bei strtok könnte man ja mit
while(token != NULL) arbeiten,
aber mit strtok_r geht das ja nicht???,....

Wie immer, fehlt mir die zündende Idee zur Vorgehensweise,....

Jemand einen Vorschlag,
Vielen Dank...
Gruß Joe

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine verkettete Liste mit den Parametern "bauen".

Autor: µC-noob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm,...????
Hä??

Danke erstmal, aber....
Ok, dann doch etwas genauer bitte,...

Gruß

Autor: µC-noob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ok,

ich nehms zurück, mit ner whiile Tuts,....

Eine Frage noch:

Hier mein code:
void splitCommand(void) //(char *rxBuffer)
{
  struct getCmd_t actCommand;

  char i = 0;
  char *testString =  ">:trigger?2?1000\0"; //">:spcSet?2?R?25?7?R\0";
  char *token;
  char *tmp;

  token = strtok_r( testString, ">:?", &tmp );
  strcpy( actCommand.cmd, token );
  while ( token != 0)
  {   i = i + 1;
    token = strtok_r( NULL, "?", &tmp ); 
    if ( i == 1 )
      strcpy( actCommand.Par1, token );  
    else if( i == 2)
      strcpy( actCommand.Par2, token );
    else if( i == 3)
      strcpy( actCommand.Par3, token );
  }

  add_menutext(&LCDLine1[0], actCommand.cmd, 0);
  add_menutext(&LCDLine2[0], actCommand.Par1, 0);
  add_menutext(&LCDLine3[0], actCommand.Par2, 0);
  add_menutext(&LCDLine4[0], actCommand.Par3, 0); 
}

aber wie kann ich jetzt dieses Hier

actCommand.Par1

dynamisch speichern
am besten so:
      char Par[5][20]; //vermutlich syntaktisch falsch???

      strcpy( actCommand.Par[i], token ); 

Nur das ist ein chararray, und dan bräucht ich nen zweifaches array,
außerdem weiß ich nicht so ganz, wie ich auf sowas zugreifen soll??

Rat?

Danke, Danke,....

Gruß

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> am besten so:
>
>       char Par[5][20]; //vermutlich syntaktisch falsch???
>
>       strcpy( actCommand.Par[i], token );

Ja, am besten so. Und vermutlich syntaktisch richtig ;-)

In Par kannst du nun bis zu 5 Tokens speichern, von denen jedes bis zu
19 Zeichen (plus die Stringendenull) lang sein darf.

Wo ist das Problem?

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

Bewertung
0 lesenswert
nicht lesenswert
> aber mit strtok_r geht das ja nicht???,....

Warum soll das mit strtok_r nicht gehen.
Beim kurzen Drüberschauen über die Doku von strtok_r
haben beide den gleichen Returnwert.

Edit: Hat sich ja mitlerweile erledigt.

Autor: µC-noob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehr schön,....

hier die Endlösung:
struct getCmd_t
{
  char  cmd[20];
  char  Par[PARA_AMOUNT][PARA_SIZE];
};

struct getCmd_t newCommand;

unsigned char splitCommand(void) //(char *rxBuffer)
{
  unsigned char i = 0;
  char *testString =  ">:spcSet?2?R?25?7?R\0";
  char *token;
  char *tmp;

  token = strtok_r( testString, "?", &tmp );
  strcpy( newCommand.cmd, token );

  while ( token != 0)
  {   
    token = strtok_r( NULL, "?", &tmp ); 
    strcpy( newCommand.Par[i], token );  
    i = i + 1;
    if( i >= ( PARA_AMOUNT - 1) )
      return 0; //not the most sensible solution but most effective!
  }
  return 1;
}

Gruß

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

Bewertung
0 lesenswert
nicht lesenswert
µC-noob wrote

>     if( i >= ( PARA_AMOUNT - 1) )
>       return 0; //not the most sensible solution but most effective!

Ein simples

      if( i == PARA_AMOUNT )
        return 0;

würde es auch tun :-)

Mit fällt auf, daß du in deiner Datenstruktur nirgends
vermerkt hast, wieviele Parameter denn nun extrahiert
werden konnten.

Das zweite: Du hast keine Sicherung eingebaut für den
Fall, dass die Parametergröße größer als PARA_SIZE wird.

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.