Hallo Leute,
folgendes Problem: Ich bekommen einen Pointer auf das erste Element
eines Strings übergeben. Dieser String ist informell durch Kommas und
Sterne unterteilt.
Nun versuche ich die jeweiligen Teilstrings mit "strtok" zu zerlegen und
in einem zwei-dimensionalen Array zu speichern.
Leider funktioniert es nicht so wie ich will.
ein Fehler ist schon Mal in
UART2_Transmit((unsigned char*) &Datafield[counter][0], 10);
sollte
UART2_Transmit((unsigned char*) &Datafield[counter-1][0], 10);
heißen!
Ne das erste kann verworfen werden, das is ok.
Das mit dem counter wieder um 1 dekrementieren ist wohl wahr^^ nichts
desto trotz werden die anderen Strings falsch ausgegeben
@Walter:
nee, das stimmt schon.
Ab dem zweiten Aufruf gibt man strtok doch NULL als
Zeiger, dann läuft es intern weiter.
Mir fehlt so ein bißchen eine vernünftige Fehlerbeschreibung...
Es sieht so aus, also ob der von strtok zurückgegebene String (bzw. die
Adresse) nicht in meinem Array gespeichert wird.
Wobei es mir solangsam dämmert. Bitte korriegiert mich, wenn ich falsch
liege:
Der aufruf mit strtok an sich stimmt. Allerdings gibt strtok einen
Pointer auf die Anfangsadresse des ermittelten Strings zurück. Daher
funktioniert das Speichern in meinen 2D-Array nicht. Vielmehr müsste ich
manuell mit strncpy arbeiten...
In etwa so:
wird nur der Zeiger ptr_Datafield erst auf ein Array-Element
gerichtet, dann gleich wieder in den zerlegten String.
Letztlich wird kein String in das Array kopiert.
Du brauchst gar kein 2D Array.
Du brauchst ein Array von Pointern in welche du die Pointer, die dir
strtok liefert, abspeicherst.
Jeder Pointer zeigt dann auf den Anfang eines Strings.
den hab ich immer noch oder sollte ich über Nacht erblindet sein:
ptr_Datafield = strtok (ptr_source, ",*");
statt
strtok (ptr_source, ",*");
ptr_Datafield ist doch nicht initialisiert, da müsste doch auch der
Compiler eine Warnung bringen!
Walter schrieb:
> den hab ich immer noch oder sollte ich über Nacht erblindet sein:> ptr_Datafield = strtok (ptr_source, ",*");> statt> strtok (ptr_source, ",*");>
Du hast nur einen Pointer!
Du brauchst aber ein Array von Pointern!
> Jeder Pointer zeigt dann auf den Anfang eines Strings.
Ohne es ausprobiert zu haben, aber ich glaub das geht nicht.
Vermuteterweise zeigt danach der Pointer auf den Anfang eines tokens
incl. dem kompletten Reststring.
Man muss also den Teilstring kopieren, denn strtok ist auf den
Eingabestring nicht destruktiv.
Ansonsten kann ich nur das Buch "C in a Nutshell" v. O'Reilly empfehlen.
Da wird sowas kompakt beschrieben.
Gruß,
Nick
Klar das würde auch gehn. Aber dann müste ich doch mit "malloc" Speicher
allokieren, damit mir die Strings nicht irgendwo im Speicher stehn.
Zumal ich strtok ja immer wieder aufrufe.
Der Quellstring ändert sich auch immer, auch in seiner Länge sowie der
Länge der jeweiligen Teistrings.
Mit der obigen Variante geh ich dabei schon eher auf Nummer Sicher.
Walter schrieb:
> den hab ich immer noch oder sollte ich über Nacht erblindet sein:
Keine Angst, du hast schon recht. Vor Allem mit der Warning - leider
scheinen gerade Anfaenger Warnings keinerlei Bedeutung beizumessen :-/
Nick Müller schrieb:
>> Jeder Pointer zeigt dann auf den Anfang eines Strings.>> Ohne es ausprobiert zu haben, aber ich glaub das geht nicht.> Vermuteterweise zeigt danach der Pointer auf den Anfang eines tokens> incl. dem kompletten Reststring.
Nein tut es nicht.
> Man muss also den Teilstring kopieren, denn strtok ist auf den> Eingabestring nicht destruktiv.
Doch, ist es.
Bitte, lest die Doku zu strtok.
strtok manipuliert den Originalstring, indem es an den Trennungsstellen
(die durch das Delimiter Token gegeben sind) '\0' einfügt!
Aus
"Hallo World"
macht strtok (mit einem Blank als Delimiter
"Hallo\0World"
Beim ersten Aufruf von strtok kriegt man einen Pointer auf das 'H'
zurück (und gleichzeitig wird das \0 eingefügt). Beim nächsten Aufruf
kriegt man einen Pointer auf das 'W' und beim dritten Aufruf kommt dann
NULL zurück.
strtok darf niemals auf String-Literale angewendet werden, weil ja der
Originalstring manipuliert wird.
Nick Müller schrieb:
>> Jeder Pointer zeigt dann auf den Anfang eines Strings.> Ohne es ausprobiert zu haben, aber ich glaub das geht nicht.
Ich verstehe ehrlich gesagt nicht, warum man sein Nichtwissen auch noch
postet, wenn man sich dessen eigentlich schon bewusst ist.
Wenn wir schon dabei sind: strtok wuerde ich mir gar nicht erst
angewoehnen, sondern gleich seinen reentranten Vetter strtok_r. Auch in
nicht parallelen Applikationen kann man mit nicht-reentranten Funktionen
sehr schnell auf die Nase fallen.
-Methode die einzelnen Strings irgendwo im Speicher des µC stehn und
evtl. andere Daten überschrieben werden könnten. Oder legt mir strtok
bei jedem Aufruf reservierte Speicherbereiche an, die NACH(!) der
while-Schleife noch existent sind? Weil erst da werden die einzelnen
Tokens weiterverarbeitet (hier zu Testzwecken eine UART-Ausgabe).
strtok gibt dir Nichts neu allokiertes zurueck, sondern lediglich einen
Pointer auf eine Position in dem String, den du uebergeben hast.
Ausserdem sucht es das Ende des Teilstuecks (anhand der uebergebenen
Tokentrenner) und setzt dort eine 0 als Terminator - es veraendert also
den String, den du uebergeben hast. Und zuguter Letzt merkt es sich, wo
es beim naechsten Aufruf weitersuchen muss.
> Bitte, lest die Doku zu strtok.
Hab ich doch. Dann ist das Buch doch nicht so toll :-) Denn das steht
da nicht drinnen. Zumindest nicht explizit.
Im "The Standard C Library" v. P.J. Plauger wirds dann klarer...
> strtok manipuliert den Originalstring, indem es an den Trennungsstellen> (die durch das Delimiter Token gegeben sind) '\0' einfügt!
War mir nicht bewusst, ist mir nie aufgefallen.
Gruß,
Nick
> Ich verstehe ehrlich gesagt nicht, warum man sein Nichtwissen auch noch> postet, wenn man sich dessen eigentlich schon bewusst ist.
Reichlich bekloppte Aussage! Damit dürften nach deiner Vorschrift keine
Fragen gestellt werden.
Dennoch Gruß,
Nick
Nick Müller schrieb:
>> Ich verstehe ehrlich gesagt nicht, warum man sein Nichtwissen auch noch>> postet, wenn man sich dessen eigentlich schon bewusst ist.> Reichlich bekloppte Aussage! Damit dürften nach deiner Vorschrift keine> Fragen gestellt werden.
Geht's noch?!? Du hast Nichts gefragt, du hast Unsinn verbreitet.
Ich bin mit Karl-Heinz oft nicht einer Meinung, aber an seinem
Fachwissen gibt es wenig zu bezweifeln, das hat er oft genug bewiesen.
Und du stellst dich da hin und erklaerst, dass du zwar keine Ahnung
hast, aber seine Ausfuehrungen einfach mal nicht glaubst. Das finde ich,
mit Verlaub gesagt, ziemlich frech.