Forum: Compiler & IDEs Anfängre string zerlgen


von Dennis S. (Gast)


Lesenswert?

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.

von Stefan E. (sternst)


Lesenswert?

strtok

von Dennis S. (Gast)


Lesenswert?

Hab ich mir auch schon angeschaut.Nur wie speichere ich dann meine 
einzelnen Werte ab für die weiter Verarbeitung?

von Thomas B. (escamoteur)


Lesenswert?

Ähm, sollst Du die Zahlenwerte speichern oder die Stringschnipsel?

Gruß
Tom

von Dennis S. (Gast)


Lesenswert?

Die Stringschnipsel.Diese soll ich später mit einer hinterlegten Liste 
verkleichen und einzelne Funktionen dadurch aufrufen.
Gruss Dennis

von Thomas B. (escamoteur)


Lesenswert?

Weißt Du von vorneherein wie viele Einträge der String hat? Bzw. wie 
lang die einzelnen Schnipsel werden können?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Dennis S. (Gast)


Lesenswert?

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.

von Thomas B. (escamoteur)


Lesenswert?

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.

von Dennis S. (Gast)


Lesenswert?

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.

von Thomas B. (escamoteur)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Dennis S. (Gast)


Lesenswert?

Ich hatte mir überlegt ein Struct zu erstellen.Dort einzelne arrays zu 
erstellen und die Torken diesen dann zuzuweisen.

von Dennis S. (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
}

von Remote O. (remote1)


Lesenswert?

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)

von Dennis S. (Gast)


Lesenswert?

Besten dank werde es jetzt mal mit deiner 2 Lösung versuchen.Geb dann 
noch mal ne Rückmeldung.

von Dennis S. (Gast)


Lesenswert?

Mein Programm läuft soweit.Besten Dank noch mal an alle.

von Thomas B. (escamoteur)


Lesenswert?

Wie hast Du es denn jetzt gelöst?

von Dennis S. (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.