Forum: Compiler & IDEs String sachgerecht tranchieren - how to-


von flyingwolf (Gast)


Lesenswert?

Hi.
Wie zerlegt man eigentlich sachgerecht einen String?
Hintergrund ist der Versuch, über die serielle Schnittstelle 
benutzerdefinierte Befehle in einen mega128 einzugeben, also z.B. time 
123400, um die Uhrzeit zu stellen.
Derzeit versuche ich das so, dass ich den String in einer for-Schleife 
Zeichen für Zeichen nach dem Leerzeichen durchsuche und ihn dann via
1
strncpy(command,(char*)&auswertstring[0],leerzeichen);
2
strcpy(wert,(char*)&auswertstring[leerzeichen+1]);
in 2 Teile zerlege. Obschon eine Ausgabe zu debuggingzwecken zeigt, das 
beide  Strings enthalten, was sie sollen, klappt die spätere Auswertung 
nicht.
Vermutlich ist das eh alles viel zu kompliziert gedacht und angestellt.
Wie macht man es besserg?



von Rolf Magnus (Gast)


Lesenswert?

Das Leerzeichen kannst du z.B. mit strchr finden. Dann gibt's noch 
strtok, welches dir das Kopieren der Stringdaten erspart, aber den 
eingegebenen String verändert (es ersetzt das gewählte Zeichen einfach 
durch den Stringterminator '\0' und gibt einen Zeiger auf das, was 
danach kommt, zurück).

> Obschon eine Ausgabe zu debuggingzwecken zeigt, das
> beide  Strings enthalten, was sie sollen, klappt die spätere Auswertung
> nicht.

Dem ersten String fehlt die Terminierung.

von Karl H. (kbuchegg)


Lesenswert?

Aus dem bischen Code, das du zeigst, kann man nicht wirklich
Rückschlüsse ziehen, wo bei dir der Fehler liegen könnte.

Solche Zerlegungen lassen sich aber gut mit strtok() und strcpy()
erledigen.

von Karl H. (kbuchegg)


Lesenswert?

Zu strtok() und der Zerlegung eines Komandos:

Vielleicht hilft dir auch das hier weiter
Beitrag "argc und **argv aus Textzeile ermitteln"
ohne dass ich viel über Strings in C schreiben muss :-)

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Wenn es darum geht etwas kompliziertere Formate zu parsen, dann bietet 
sich vielleicht Ragel an:
http://www.cs.queensu.ca/~thurston/ragel/

von Der F. (zotos)


Lesenswert?

Karl heinz Buchegger wrote:
> Zu strtok() und der Zerlegung eines Komandos:
>
> Vielleicht hilft dir auch das hier weiter
> Beitrag "argc und **argv aus Textzeile ermitteln"
> ohne dass ich viel über Strings in C schreiben muss :-)

Der Thread hinter dem Link von Karl Heinz basiert genau auf der Gleichen 
Aufgabenstellung.

Ich Habe eine Art Kommandozeile via Terminal und RS232 auf dem 
Controller realisiert.

Die Idee war es die Argumente und einen Argumenten Zähler an Funktionen 
zu übergeben. Dazu die vom PC bekannten argc und **argv Parameter zu 
benutzen.

Karl Heinz hat dort nicht nur die Lösung für die Umsetzung geliefert 
sondern es auch so erklärt das es wirklich gut zu verstehen ist. Danke 
noch mal.


von Rolf Magnus (Gast)


Lesenswert?

> Karl Heinz hat dort nicht nur die Lösung für die Umsetzung geliefert
> sondern es auch so erklärt das es wirklich gut zu verstehen ist.

Das macht der immer. Richtig beängstigend ;-)

von flyingwolf (Gast)


Lesenswert?

Vielleicht würde es helfen wenn ich was von C-Programmierung verstehen 
würde ...
Wunderbarer Weise gibt es nicht eine Zeile in Deinem Programm, von der 
ich behaupten könnte dass ich sie lückenlos nachvollziehen kann.
Schon    int main()    ist mir ein Rätsel. An wen soll main denn die "0" 
zurückschicken und warum? Welches Zeichen ist "/0"? 0x00? Was macht 
eigentlich NULL? Was ist "\t"? Was passiert bei argv++ ? Ist argv zu 
diesem Zeitpunkt nicht "Dies ist   ein Test" oder zumindest ein Zeiger 
dahin?
printf kann ich wunderpar für PC-Programme verwenden weil da die 
Standartausgabe der Bildschirm ist, aber am mega128 ist kein Bildschirm 
dran, nur das weiss printf eben nicht ;-) .
Vielleicht läßt sich die Erklärung ja auf ein etwas niedrigeres Niveau 
ausdehnen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Literaturhinweis:

Kernighan & Ritchie, Programmieren in C, zweite Auflage, Hanser-Verlag

Das klärt annähernd so gut wie alle Fragen des Flugwolfes - bis auf die 
embedded-spezifische Dinge (wohin gibt printf seine Daten aus?)

printf gibt auf jedem System seine Daten an stdout aus - und das ist auf 
PCs üblicherweise mit dem Textbildschirm verknüpft. Auf dem AVR kann es 
mit der seriellen Schnittstelle verheiratet* werden, und so landen 
Ausgaben auf einem angeschlossenen seriellen Terminal (oder einem PC mit 
einem Terminalemulator à la Hyperterm).

*) eigene putchar-Funktion implementieren, siehe Dokumentation des 
Compilers/dessen Standard-Library

von flyingwolf (Gast)


Lesenswert?

Literaturhinweis:
Kernighan & Ritchie,

Oh ja, das Werk kenne ich. Ich werfe ja Bücher in der Regel nicht weg, 
ganz schlechte verleihe ich höchstens in der Hoffnung, sie nicht 
zurückzubekommen, aber das konnte ich noch nicht einmal an jemanden 
verleihen. Sorry. Ich weiss das dieses Buch hier als die Bibel gehandelt 
wird, aber vielleicht liegt es an meiner atheistischen Seele, das ich 
mit diesem Buch absolut nichts anfangen kann. Ich finde nichts darin, 
die Erklärungen verstehe ich nicht und  wenn ich gezielt etwas suche, 
finde ich es nicht.
Mr Bucheggers Beispiel werde ich mir heute Abend mit meiner M&T-Schwarte 
zerpflücken und dann wird hoffentlich einiges klarer.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die zweite Auflage kannst Du nicht meinen.

Die erste ist grottenschlecht, und die würde ich auch entsorgen. Die 
beschreibt auch kein ANSI-C (C89), sondern dessen "K&R-C" genannten 
Vorgänger.

Die zweite hingegen beschreibt in verständlicher Weise alles, was man 
über C wissen muss -mit Ausnahme von "embedded-Spezialitäten".

von Rolf Magnus (Gast)


Lesenswert?

> Vielleicht würde es helfen wenn ich was von C-Programmierung verstehen
> würde ...

Schaden würde es sicher nicht.

> Schon    int main()    ist mir ein Rätsel. An wen soll main denn
> die "0" zurückschicken und warum?

An den Aufrufer des Programms. Bei einem µC ohne Betriebssystem gibt's 
zwar meistens keinen, aber die Regel in C ist nunmal, daß main() immer 
einen int zurückliefern muß. Dabei gibt es die Werte 0, EXIT_SUCCESS und 
EXIT_FAILURE (die letzten beiden sind in stdlib.h definiert). 0 ist 
dabei mit EXIT_SUCCESS gleichbedeutend.

> Welches Zeichen ist "/0"? 0x00?

Meinst du '\0'? Das ist der Stringterminierer, also das Zeichen, das das 
Ende eines Strings markiert.

> Was macht eigentlich NULL?

Das ist ein Platzhalter für einen Nullzeiger, also einen, den man 
explizit auf nichts zeigen lassen will.

> Was ist "\t"?

Ein Tabulator. Aber im Programm steht " \t", also ein Leerzeichen und 
ein Tabulator.

> Was passiert bei argv++ ?

argv wird inkrementiert. Es handelt sich um einen Zeiger auf das erste 
Element eines Arrays. Nach dem Inkrementieren zeigt er auf das zweite.

> Ist argv zu diesem Zeitpunkt nicht "Dies ist   ein Test" oder zumindest
> ein Zeiger dahin?

argv (das vor dem Inkrementieren) ist ein zeiger auf "Dies". Nach dem 
Inkrementieren zeigt es auf "ist".

> printf kann ich wunderpar für PC-Programme verwenden weil da die
> Standartausgabe der Bildschirm ist, aber am mega128 ist kein Bildschirm
> dran, nur das weiss printf eben nicht ;-) .

Du kannst ihn aber z.B. über einen max232 an den seriellen Port des PCs 
anschließen und eine kleine Funktion schreiben, die dann von printf für 
die Ausgabe verwendet wird. Dazu mußt du allerdings weit genug sein, um 
das erstmal zustandezubringen.

> Vielleicht läßt sich die Erklärung ja auf ein etwas niedrigeres Niveau
> ausdehnen.

Ich würde sagen, du solltest erstmal bei der Programmierung auf dem PC 
bleiben, und erst wenn du C einigermaßen begriffen hast dann auf einen 
µC umsteigen, denn da ist alles noch eine Stufe komplizierter.

von Gast (Gast)


Angehängte Dateien:

Lesenswert?

Aber Hallo.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Google-Anzeigen hat eben vollautomatisch erkannt, daß es hier um 
"Strings" geht.

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.