Hallo ich arbeite gerade an einem kleinen Projekt für meinen Professor.Leider bin ich noch recht neu im Umgang mit C.Darum bitte ich um Entschuldigung für mein Unverständnis.Hier mein Problem ich bekomme einen String z.b "34,567,55,77". Diesen soll ich nun anhand der Kommas zerlegen und zwischenspeichern für eine spätere Verarbeitung. Besetn dank schon mal für die Hilfe.
Hab ich mir auch schon angeschaut.Nur wie speichere ich dann meine einzelnen Werte ab für die weiter Verarbeitung?
Ähm, sollst Du die Zahlenwerte speichern oder die Stringschnipsel? Gruß Tom
Die Stringschnipsel.Diese soll ich später mit einer hinterlegten Liste verkleichen und einzelne Funktionen dadurch aufrufen. Gruss Dennis
Weißt Du von vorneherein wie viele Einträge der String hat? Bzw. wie lang die einzelnen Schnipsel werden können?
Dennis S. schrieb: > Die Stringschnipsel.Diese soll ich später mit einer hinterlegten Liste > verkleichen und einzelne Funktionen dadurch aufrufen. Das kommt jetzt drauf an. strtok ermöglicht dir 2 Arten der Weiterverwendung Die eine ist: du kopierst die Einzelteile in neue Strings um (also jeweils in eigene char Arrays) Die andere ist: strtok hinterlässt den String in einer Form, dass man Pointer in den Originalstring als neue Stringanfänge bekommt, so dass man dem weiterverabeitende Programm auch hier ein 'Array von Strings' unterjubeln kann, welches in Wirklichkeit nur aus Pointern in ein und denselben String besteht. Hier hat man also gewisse Freiheiten, um sich an der Weiterverarbeitung der Einzelteile zu orientiern und die Verwendung von strtok daran anzupassen.
Der String besteht im moment aus 4 Teilen diese können einzelnd bis zu 20 Zeichen enthalten.Kann sein das da aber noch mehr hinzukommt.
Karl heinz Buchegger schrieb: > welches in Wirklichkeit nur aus Pointern in ein und > denselben String besteht. Hatte ich auch schon überlegt. Kommt halt drauf an, ob der Orginalstring erhalten bleibt. Wäre schon elegant. Dann kann er aber auch einfach den String durchlaufen und bei jedem Komma einen neuen Pointer setzen und das Komma durch eine \0 ersetzen.
Ich denke ich würde die einzelnen Teile in neue Strings kopieren.Ist für mich glaube ich dann erst mal einfacher zu verstehen. Besten dank schon mal für die Hilfsbereitschaft hier.
Zwei Möglichkeiten: 1. Mach ne verkettete Liste mit je einem Eintrag für jeden Substring der Dynamisch allokiert wird, dann bist Du super flexibel und verbrauchst nicht unnötig Speicher. 2. Ermittle zuerst wie viele Einträge der Orginalstring hat und die groß der längste davon ist und allokier ein array char[length][size] und trag da die Schnipsel ein. Ist natürlich je nachdem wie groß die Länge der Einträge scwankt etwas Speicherverschwendung. Gruß Tom
Thomas Burkhart schrieb: > Karl heinz Buchegger schrieb: >> welches in Wirklichkeit nur aus Pointern in ein und >> denselben String besteht. > > Hatte ich auch schon überlegt. Kommt halt drauf an, ob der Orginalstring > erhalten bleibt. > > Wäre schon elegant. Dann kann er aber auch einfach den String > durchlaufen und bei jedem Komma einen neuen Pointer setzen und das Komma > durch eine \0 ersetzen. Ja, klar. strtok hat ein paar (für manche Zwecke) unangenehme Eigenschaften. zb werden mehrere hintereinderliegende gleiche Trennzeichen übersprungen. Das kann manchmal gewollte sein (wenn es zb gilt die Trennung über Leerzeichen zu machen) ist aber manchmal ein echter Show-Stopper.
Dennis S. schrieb: > Ich denke ich würde die einzelnen Teile in neue Strings kopieren.Ist für > mich glaube ich dann erst mal einfacher zu verstehen. Das kommt drauf an. Stringhandling in C, mit Strings deren Länge man im Vorraus nicht kennt, ist eine recht unangenehme Sache.
Ich hatte mir überlegt ein Struct zu erstellen.Dort einzelne arrays zu erstellen und die Torken diesen dann zuzuweisen.
Bei meinem Programm ist nur ein Trennzeichen vorgesehen.Denke mal die einzelnen Teilsstrings werden nicht grösser als 30-40 Zeichen was ich so rausgehört habe.
Aber um mal etwas Leben in die Bude zu bekommen
1 | #include <stdio.h> |
2 | #include <string.h> |
3 | |
4 | int main(void) |
5 | {
|
6 | |
7 | {
|
8 | // einfach einen Token nach dem anderen ausgeben.
|
9 | // Das benutzt man wenn man nicht alle token in einem Rutsch braucht
|
10 | char string[] = "command,arg1, arg2"; |
11 | char *token; |
12 | token = strtok( string, ", " ); // zerlegt wird an , und Leerzeichen |
13 | while( token != NULL ) |
14 | {
|
15 | printf( "%s\n", token ); |
16 | token = strtok( NULL, ", " ); /* weitere Token ermitteln */ |
17 | }
|
18 | }
|
19 | |
20 | printf( "\n\n" ); |
21 | |
22 | {
|
23 | // hier werden alle Token zwischengespeichert (Pointer in den Originalstring)
|
24 | // das braucht man, wenn zb eine Funktion aufgerufen wird, die alle
|
25 | // Token auf einmal braucht
|
26 | char string[] = "command,arg1, arg2"; |
27 | char *token; |
28 | char* tokens[20]; |
29 | int nrTokens = 0; |
30 | int i; |
31 | |
32 | token = strtok( string, ", " ); // zerlegt wird an , und Leerzeichen |
33 | while( token != NULL ) |
34 | {
|
35 | tokens[nrTokens++] = token; |
36 | token = strtok( NULL, ", " ); /* weitere Token ermitteln */ |
37 | }
|
38 | |
39 | for( i = 0; i < nrTokens; i++ ) |
40 | printf( "%s\n", tokens[i] ); |
41 | }
|
42 | |
43 | return 0; |
44 | }
|
Für mein Handy-Projekt lese ich empfangene SMS aus und suche nach bestimmten "Command Strings" Dazu habe ich mir eine struct gebaut:
1 | typedef struct SMS_CMD_LIST_S{ |
2 | char cmd[10]; /**< Zeichenkette für Kommando */ |
3 | uint8_t (*fp)(uint8_t dat); /**< Funktionspointer auf Funktion, welche Kommando \ref cmd zugeordnet werden soll */ |
4 | }SMS_CMD_LIST_T; |
5 | |
6 | const SMS_CMD_LIST_T sms_cmd_list[] = { |
7 | {"set",sms_cmdset} |
8 | };
|
Den empfangenen String durchsuche ich ebenfalls mit strtok. Mit Hilfe von qsort und bsearch vergleiche ich dann mit dem Kommand string:
1 | #define SMS_DELIMITER ",;: "
|
2 | |
3 | // Kommando aus empfangener SMS auslesen
|
4 | char *ptr_nachricht; |
5 | char nachricht[161]; // strtok verändert string --> Kopie anlegen |
6 | SMS_CMD_LIST_T keyItem = {"",NULL}; |
7 | strcpy(nachricht,sms_dec_data.nachricht); |
8 | //nachricht in Kleinbuchstaben umwandeln
|
9 | ptr_nachricht = nachricht; // Startadresse übergeben |
10 | while(*ptr_nachricht){ |
11 | if (*ptr_nachricht >= 'A' && *ptr_nachricht <= 'Z') { |
12 | *ptr_nachricht = *ptr_nachricht - 'A' + 'a'; |
13 | }
|
14 | ptr_nachricht++; |
15 | }
|
16 | // sortieren der Befehlsliste (Voraussetzung für bsearch)
|
17 | char *tmp; |
18 | qsort(&sms_cmd_list, (sizeof(sms_cmd_list)/sizeof(SMS_CMD_LIST_T)), sizeof(SMS_CMD_LIST_T), (int(*)(const void*,const void*))strcmp); |
19 | ptr_nachricht = strtok_r(nachricht,SMS_DELIMITER,&tmp); // ersten Befehl extrahieren |
20 | while (ptr_nachricht!=NULL){ |
21 | // Befehle entsprechend Liste ausführen
|
22 | strcpy(keyItem.cmd,ptr_nachricht); // gefundenes Kommando übergeben |
23 | SMS_CMD_LIST_T* spItem = (SMS_CMD_LIST_T*)bsearch (&keyItem, sms_cmd_list, (sizeof(sms_cmd_list)/sizeof(SMS_CMD_LIST_T)), sizeof(SMS_CMD_LIST_T), (int(*)(const void*,const void*)) strcmp); |
24 | if (spItem != NULL) { spItem->fp(0); } |
25 | ptr_nachricht = strtok_r(NULL,SMS_DELIMITER,&tmp); // neues Kommando suchen (falls mehrerer vorhanden sind) |
26 | }
|
Wenn ich das richtig verstanden habe, sollte das genau das sein was du suchst. Schaus dir einfach mal an (inklusive der reference zu den einzelnen Funktionen)
Besten dank werde es jetzt mal mit deiner 2 Lösung versuchen.Geb dann noch mal ne Rückmeldung.
Ich teile meinen String mit strtok auf und kopiere dann die Daten mit strcpy auf meinene im strcut festgelegten Parameter. Besten dank noch mal für die tolle Hilfe hier.
Dennis S. schrieb: > Ich teile meinen String mit strtok auf und kopiere dann die Daten mit > strcpy auf meinene im strcut festgelegten Parameter. Wo kommt der Originalstring her? Besteht die Möglichkeit, dass der String fehlerhaft ist? Wenn den ein Benutzer eingibt, musst du immer damit rechnen, dass der fehlerhaft ist! Kriegst du den von einer Schnittstelle von einem anderen Programm zugespielt, reicht es die Maximallänge zu testen. Aber selbst dann sollte man im Hinterkopf behalten, dass die zur Verfügung stehenden char-Arrays nicht überlaufen werden. (Deshalb ist die Lösung mit umkopieren nicht unbedingt die Methode der Wahl. Man muss viel Aufwand treiben um Fehlbedienung auszuschliessen)
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.