Forum: Mikrocontroller und Digitale Elektronik C String nach Zeichen zerlegen


von Arnaud (Gast)


Lesenswert?

Hallo,

biete um Hilfe.
Habe einen String

unit8 String[100] = "Kessel1:2:1:50:128:2:8000" (ist nicht alles, geht 
so weiter)

Ich möchte die Zahlen aus diesem String auslesen.
Programmiere in C
Kessel1 ist der Indikator, von wo das kommt, der ist auch wichtig.
ich benötige die Zahlen 2,1,50,128,2,8000.
Und diese sollen in die Int Variablen geschrieben werden.

Mir ist bekannt, dass dieses Thema schon millionenfach diskutiert wurde, 
ich verstehe das leider beim besten Willen nicht.

Der String ist relativ lang.
Lässt sich das mit scanf lösen?
Oder muss man dafür eine Schleife schreiben, die alle : prüft?

Vielen Dank
Arnaud

von Tom (Gast)


Lesenswert?


von Harry L. (mysth)


Lesenswert?


von Arnaud (Gast)


Lesenswert?

Vielen Dank, da war ich leider schon.
Zu kompliziert für mich

Wer kann mir das bei scanf %[^:]:%d erklären
was passier beim zweiten : genau?

von Dirk B. (dirkb2)


Lesenswert?

Arnaud schrieb:
> Lässt sich das mit scanf lösen?

Ja.

Arnaud schrieb:
> Wer kann mir das bei scanf %[^:]:%d erklären
> was passier beim zweiten : genau?

Es wird überlesen.

%[^:] liest alle Zeichen bis auf den :
Der steht also noch drin.
Mit dem folgenden : wird der dann auch überlesen.
Mit dem folgenden %d wird eine Dezimalganzzahl eingelesen.

von Dirk B. (dirkb2)


Lesenswert?

strtok ist nicht nötig. das ist auch etwas doof, da der Originalstring 
zerstört wird.

Bei der Standardfunktion strtol kann man den Parameter **endptr auf den 
: auswerten bzw. für das folgende strtol verwenden.

strtol wird ja sowieso für die Umwandlung der Zahlen gebraucht.

von Axel S. (a-za-z0-9)


Lesenswert?

Arnaud schrieb:

[ strtok() ]

> Vielen Dank, da war ich leider schon.
> Zu kompliziert für mich

Das ist schade. Für dich. Such dir ein einfacheres Hobby.
Vielleicht was mit Bienen? Und Blümchen?

von zitter_ned_aso (Gast)


Lesenswert?

1
    char str[100] = "sensor1:100:200:300:400";                                                                                          
2
                                                                                                                                        
3
    char sensor_name[15];                                                                                                               
4
    int data[4];                                                                                                                        
5
                                                                                                                                        
6
    sscanf(str, "%[^:]%*c%d%*c%d%*c%d%*c%d", sensor_name, &data[0],                                                                     
7
            &data[1], &data[2], &data[3]);                                                                                              
8
                                                                                                                                        
9
    printf("sensor: %s\ndata: %d, %d, %d, %d\n", sensor_name,                                                                           
10
            data[0], data[1], data[2], data[3]);

Mit %*c wird das Trennzeichen ":" übersprungen.

stackoverlow sei dank:
https://stackoverflow.com/questions/13757430/sscanf-delimiters-for-parsing/13757540


Ich würde lieber strtok(...) nehmen.

von zitter_ned_aso (Gast)


Lesenswert?

einen gemütlichen ersten Advent allerseits ;-)

von Zeno (Gast)


Lesenswert?

Dirk B. schrieb:
> strtok ist nicht nötig. das ist auch etwas doof, da der Originalstring
> zerstört wird.

Nö strok ist schon in Ordnung. Falls man den String wirklich noch mal 
brauchen sollte, kann man sich ja eine Kopie anfertigen und diese 
zerlegen.

Mit strok kann man flexibler auf unterschiedlich lange Strings 
reagieren.

von Rolf M. (rmagnus)


Lesenswert?

Arnaud schrieb:
> Der String ist relativ lang.
> Lässt sich das mit scanf lösen?
> Oder muss man dafür eine Schleife schreiben, die alle : prüft?

Das hängt nicht davon ab, wie lang der String ist, sondern ob die Anzahl 
der Felder immer gleich ist oder variieren kann.

von Dirk B. (dirkb2)


Lesenswert?

Rolf M. schrieb:
> Das hängt nicht davon ab, wie lang der String ist, sondern ob die Anzahl
> der Felder immer gleich ist oder variieren kann.

Wenn die Reihenfolge bleibt, kann man den Rückgabewert von scanf 
auswerten und entsprechend reagieren.

Wenn man statt %*c den : in den Formatstring schreibt, braucht man den 
auch gar nicht mehr überprüfen.

Ohne scanf und strtok
1
char *endptr;
2
int data[ANZSENSOREN];
3
int i=0;
4
5
endptr = strchr(str,':');
6
while (endptr && (*endptr == ':')
7
{ data[i++] = strtol(endptr+1,&endptr);
8
  if (i >= ANZSENSOREN) break;
9
}

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Zeno schrieb:
> Nö strok ist schon in Ordnung. Falls man den String wirklich noch mal
> brauchen sollte, kann man sich ja eine Kopie anfertigen und diese
> zerlegen.
>
> Mit strok kann man flexibler auf unterschiedlich lange Strings
> reagieren.

Kopien von Strings, deren Länge vorher unbekannt ist, ist in C eine 
beliebte Fehlerquelle.

Zudem kann man strtok nicht gleichzeitig auf verschiedene Strings laufen 
lassen.

von Markus F. (mfro)


Lesenswert?

Arnaud schrieb:
> Habe einen String
>
> unit8 String[100] = "Kessel1:2:1:50:128:2:8000" (ist nicht alles, geht
> so weiter)

Vielleicht ist dein Problem ja einfach eine Ebene weiter oben?

Entweder Du liest den String von irgendwoher ein (dann könntest Du ihn 
gleich beim Einlesen an Ort und Stelle in die für dich relevanten 
Einzelteile zerlegen) oder Du hast ihn wie geschrieben "am Stück" als 
Konstante im Programm: dann solltest Du dir überlegen, ob das so 
geschickt  und nicht vielleicht besser in mehreren Variablen (oder 
struct-Membern) unterzubringen ist.

Beitrag #6058007 wurde von einem Moderator gelöscht.
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.