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
Schau dir strtok() an. Mit dieser Funktion ist das nicht weiter problematisch.
Hi, danke erstmal, strtok, gibt es in meiner Bibliothek nicht, aber dafür strtok_r Folgendes Programm steht:
1 | struct getCmd_t |
2 | {
|
3 | char cmd[20]; |
4 | char Par1[20]; |
5 | char Par2[20]; |
6 | char Par3[20]; |
7 | };
|
8 | |
9 | void splitCommand(void) //(char *rxBuffer) |
10 | {
|
11 | struct getCmd_t actCommand; |
12 | |
13 | char *testString = ">:trigger?2?1000\0"; //">:spcSet?2?R?25?7?R\0"; |
14 | char *token; |
15 | char *tmp; |
16 | |
17 | token = strtok_r( testString, ">:?", &tmp ); |
18 | strcpy( actCommand.cmd, token ); |
19 | |
20 | token = strtok_r( NULL, "?", &tmp ); |
21 | strcpy( actCommand.Par1, token ); |
22 | |
23 | token = strtok_r( NULL, "?", &tmp ); |
24 | strcpy( actCommand.Par2, token ); |
25 | |
26 | token = strtok_r( NULL, "?", &tmp ); |
27 | strcpy( actCommand.Par3, token ); |
28 | |
29 | add_menutext(&LCDLine1[0], actCommand.cmd, 0); |
30 | add_menutext(&LCDLine2[0], actCommand.Par1, 0); |
31 | add_menutext(&LCDLine3[0], actCommand.Par2, 0); |
32 | add_menutext(&LCDLine4[0], actCommand.Par3, 0); |
33 | }
|
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
Ähm,...???? Hä?? Danke erstmal, aber.... Ok, dann doch etwas genauer bitte,... Gruß
Ok, ok, ich nehms zurück, mit ner whiile Tuts,.... Eine Frage noch: Hier mein code:
1 | void splitCommand(void) //(char *rxBuffer) |
2 | {
|
3 | struct getCmd_t actCommand; |
4 | |
5 | char i = 0; |
6 | char *testString = ">:trigger?2?1000\0"; //">:spcSet?2?R?25?7?R\0"; |
7 | char *token; |
8 | char *tmp; |
9 | |
10 | token = strtok_r( testString, ">:?", &tmp ); |
11 | strcpy( actCommand.cmd, token ); |
12 | while ( token != 0) |
13 | { i = i + 1; |
14 | token = strtok_r( NULL, "?", &tmp ); |
15 | if ( i == 1 ) |
16 | strcpy( actCommand.Par1, token ); |
17 | else if( i == 2) |
18 | strcpy( actCommand.Par2, token ); |
19 | else if( i == 3) |
20 | strcpy( actCommand.Par3, token ); |
21 | }
|
22 | |
23 | add_menutext(&LCDLine1[0], actCommand.cmd, 0); |
24 | add_menutext(&LCDLine2[0], actCommand.Par1, 0); |
25 | add_menutext(&LCDLine3[0], actCommand.Par2, 0); |
26 | add_menutext(&LCDLine4[0], actCommand.Par3, 0); |
27 | }
|
aber wie kann ich jetzt dieses Hier actCommand.Par1 dynamisch speichern am besten so:
1 | char Par[5][20]; //vermutlich syntaktisch falsch??? |
2 | |
3 | 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ß
> 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?
> 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.
Sehr schön,.... hier die Endlösung:
1 | struct getCmd_t |
2 | {
|
3 | char cmd[20]; |
4 | char Par[PARA_AMOUNT][PARA_SIZE]; |
5 | };
|
6 | |
7 | struct getCmd_t newCommand; |
8 | |
9 | unsigned char splitCommand(void) //(char *rxBuffer) |
10 | {
|
11 | unsigned char i = 0; |
12 | char *testString = ">:spcSet?2?R?25?7?R\0"; |
13 | char *token; |
14 | char *tmp; |
15 | |
16 | token = strtok_r( testString, "?", &tmp ); |
17 | strcpy( newCommand.cmd, token ); |
18 | |
19 | while ( token != 0) |
20 | {
|
21 | token = strtok_r( NULL, "?", &tmp ); |
22 | strcpy( newCommand.Par[i], token ); |
23 | i = i + 1; |
24 | if( i >= ( PARA_AMOUNT - 1) ) |
25 | return 0; //not the most sensible solution but most effective! |
26 | }
|
27 | return 1; |
28 | }
|
Gruß
µ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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.