Das alte Märchen von der Stringverarbeitung mit strtok
-
Hi,
ich habe ein Problem mit einer Funktion die einen String parsen soll.
Der String sieht in etwa so aus: "0,0,0;0,0,0;0,0,0;0,0,0*Chksum"
In der ersten Funktion soll der String zerlegt werden in:Str1: 0,0,0 Str2: 0,0,0 Str3: 0,0,0 Str4: 0,0,0
Die Teilstrings sollen dann in Zahlen zerlegt und als float gespeichert werden.
Str1: 0,0,0: float one = 0; float two = 0; float thr = 0;
Der erste Teil scheint auch bisher zu funktionieren. Beim zweiten Teil hapert es allerdings.
Bisher bekomme ich da nur Zeichenmüll und der String im buffer scheint auch nach dem Aufruf von "parse_PID" zerstört zu werden.
Ich kann aber irgendwie keinen offensichtlichen Fehler finden?!// kP, kI, imax float *parse_PID(char* buffer) { static float res_pid[PID_SIZE]; // PID_SIZE ist 3 (Makro def) if(buffer != NULL) { char *sub_cstr = strtok (buffer, ","); for(int i = 0; i < PID_SIZE && sub_cstr != NULL; i++) { sub_cstr = strtok (NULL, ","); res_pid[i] = atof(sub_cstr); } } return res_pid; } bool config_pids(char* buffer) { // process cmd char *str = strtok(buffer, "*"); char *chk = strtok(NULL, "*"); if(verify_chksum(str, chk) ) { float *pids = NULL; char *sub_cstr; int i = 0; do { if(i == 0) sub_cstr = strtok (str, ";"); else sub_cstr = strtok (NULL, ";"); pids = parse_PID(sub_cstr); if(pids == NULL) return false; switch(i) { case 0: PIDS[PID_PIT_RATE].kP(pids[0]); PIDS[PID_PIT_RATE].kI(pids[1]); PIDS[PID_PIT_RATE].imax(pids[2]); break; case 1: PIDS[PID_ROL_RATE].kP(pids[0]); PIDS[PID_ROL_RATE].kI(pids[1]); PIDS[PID_ROL_RATE].imax(pids[2]); break; case 2: PIDS[PID_YAW_RATE].kP(pids[0]); PIDS[PID_YAW_RATE].kI(pids[1]); PIDS[PID_YAW_RATE].imax(pids[2]); break; case 3: PIDS[PID_PIT_STAB].kP(pids[0]); PIDS[PID_ROL_STAB].kP(pids[1]); PIDS[PID_YAW_STAB].kP(pids[2]); break; } i++; } while(sub_cstr != NULL); } else { hal.console->printf("Invalid checksum\n"); memset(buffer, 0, sizeof(buffer)); // flush buffer after everything } return true; }
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum C (C89, C99 und C11) verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Richtig erkannt.
strtok ist nicht nur nicht multithreadfähig und nicht reentrant, es wird auch der Basisstring zerstört.
ist die Anzahl der Teile konstant? -> sscanf
sonst strsep,strtok_r,strtok_s
-
strtok
schreibt an die Stelle der token den Stringterminator '\n' und merkt sich den aktuellen Zustand vom String.Wenn als erster Paramter ein Wert !=
NULL
kommt, wird von eienm neuen String ausgegangen.Dadurch wird der String zerstört und du kannst
strtok
nicht verschachteln oder gleichzeitig auf verschiedene Strings anwenden.Deine do-while-Schleife ist etwas merkwürdig aufgebaut
Zeile 61 macht auch nicht das, was du meinst.Nimm sscanf zumindest für die PID.
Oder gleich für Alles. Dann ist das ein Einzeiler.
-
DirkB schrieb:
strtok
schreibt an die Stelle der token den Stringterminator '\n'Schwachfug.
Das ist natürlich '\0'