Hallo,
ich versuche einen String auszuwerten, welchen ich über den UART
empfange.
Der String hat das Format x;xxxx
1
unsignedintc,c_temp,num_temp;
2
char*abschnitt;
3
chardelimiter[]=";";
4
5
uart_gets(Line,sizeofLine);
6
abschnitt=strtok(Line,delimiter);
7
c_temp=abschnitt;
8
while(abschnitt!=NULL)
9
{
10
abschnitt=strtok(NULL,delimiter);
11
num_temp=abschnitt;
12
}
13
if(c_temp&UART_NO_DATA)
14
{
15
/* no data available from UART */
16
}
17
else
18
{
19
c=c_temp;
20
}
21
switch(c)
22
{
23
case'a':
24
// mache etwas
25
break;
26
27
case'b':
28
...
29
}
Der String wird korrekt empfangen, der erste Teil vorm Trennzeichen auch
korrekt in c_temp geschrieben.
Der zweite Teil des Strings landet schonmal nicht da wo er hin soll,
d.h. num_temp ist leer.
Die switch-case Anweisung wird allerdings auch ignoriert, und es wird in
den default-Zweig gesprungen (selbst wenn in c ein a steht).
Vielleicht sieht ja jemand gleich den Fehler.
S. Q. schrieb:> Die switch-case Anweisung wird allerdings auch ignoriert, und es wird in> den default-Zweig gesprungen (selbst wenn in c ein a steht).
In c wird nie ein a stehen, da du die Adresse, die von strtok
zurückgegeben wird, dort speicherst. Die Warnungen sollten dir auch
mitgeteilt haben, daß du da Zeiger und nicht-Zeiger munter mischst.
S. Q. schrieb:> Zeiger sind nicht so meine Welt,
Im Ernst, dann solltest du das zu allererst ändern oder auf Basic
umschwenken. C ohne Zeiger ist wie Auto fahren nur im ersten Gang mit
Standgas.
> der erste Teil vorm Trennzeichen auch> korrekt in c_temp geschrieben.
in c-temp wird überhaupt kein String geschrieben.
c_temp ist ein Zeiger auf den Anfang des ersten Teilstrings. Der String
selbst existiert nach wie vor nur in 'Line' (welches du hoffentlich
korrekt als Array definiert hast.
Du hast also von gets einen String gekriegt
Line
+---+---+---+---+---+---+---+---+---+---+
| a | ; | x | y | z | \0| | | | |
+---+---+---+---+---+---+---+---+---+---+
strtok liefert dir einen Pointer auf den Anfang des Teilstrings, der mit
dem gesuchten Delimiter beendet ist.
abschnitt=strtok(Line,delimiter);
Line
+---+---+---+---+---+---+---+---+---+---+
| a | ; | x | y | z | \0| | | | |
+---+---+---+---+---+---+---+---+---+---+
^
|
|
+-----+
| o |
+-----+
abschnitt
machst du jetzt einen
c_temp=abschnitt;
dann kopierst du den Pointer in abschnitt. D.h. du erzeugst
Line
+---+---+---+---+---+---+---+---+---+---+
| a | ; | x | y | z | \0| | | | |
+---+---+---+---+---+---+---+---+---+---+
^^
|+-------------+
| |
+--|--+ +--|--+
| o | | o |
+-----+ +-----+
abschnitt c_temp
(mal abgesehen davon, dass du mit c_temp den falschen Datentyp hast).
Aber kopiert wird der Wert vom Pointer und nicht das worauf er zeigt.
wenn du einen Pointer hast, zum Beispiel 'abschnitt' und du
interessierst dich für den WErt an der Stelle an der der Pointer
hinzeigt, dann musst du den Pointer dereferenzieren. In C macht man das,
in dem man dem Pointer einen * voranstellt.
c_temp = *abschnitt;
Line
+---+---+---+---+---+---+---+---+---+---+
| a | ; | x | y | z | \0| | | | |
+---+---+---+---+---+---+---+---+---+---+
^
|
|
+-----+
| o |
+-----+
abschnitt
abschnitt das ist der Pointer, such ihn in der Zeichnung
*abschnitt jetzt verfolgst du den Pfeil, wo der hinführt
und holst dir von dort den Wert. In diesem Fall
ist das das 'a', weil ja der Pfeil dort hin
führt.
c_temp = *abschnitt; und dieses 'a' kannst du jetzt in c_temp
speichern
Line
+---+---+---+---+---+---+---+---+---+---+
| a | ; | x | y | z | \0| | | | |
+---+---+---+---+---+---+---+---+---+---+
^
|
|
+-----+ +---+
| o | | a |
+-----+ +---+
abschnitt c_temp
Kleiner *, große Wirkung.
> Zeiger sind nicht so meine Welt
Dann besorg dir ein C-Buch, arbeite die Kapitel über Arrays und Pointer
durch und mach die Übungen im Buch. Aber "Zeiger sind nicht so meine
Welt" ist keine akzeptable Aussage. 60% der C-Programmierung dreht sich
um Pointer und Arrays und wie das alles zusammenhängt. Und von den
restlichen 40% sind 95% Strukturen, Files und dynamischen
Datenstrukturen gewidment. Der noch fehlende Rest ist Pipifax. Und so
wie es aussieht, ist gerade mal dieser Pipifax "deine Welt". Und das ist
für einen C-Programmierer nicht akzeptabel.
Das nenn ich mal eine Erklärung. Danke schön. Auch für die Ohrfeigen...
Da ich damit mein Geld nicht verdiene, kann ich mir das ganz gut
verzeihen. Natürlich ist es nützlich es zu können, aber ich denke die
wenigsten sind damit zur Welt gekommen.
Es heißt ja auch immer "Wer nicht fragt bleibt dumm."
Den Gedanken das C-Buch mal zu suchen werden ich mal genauer in Betracht
ziehen und die Beispiele mal durch nehmen.
Danke nochmals.
So weit, so schlecht. Ich habe jetzt die Variablendeklaration geändert.
c_temp erhält jetzt den Inhalt von *abschnitt. Der zweite Aufruf von
strtok schreibt mir allerdings nichts in num_temp.
Der zweite Aufruf müsste doch nun auf die Adresse des 'x' (lt. Bsp.
K.-H. B.) zeigen und mir die Dereferenzierung den Inhalt in num_temp
schreiben.
Mein eigentlicher Plan war es über uart_getc ein Zeichen zu Empfangen
und damit in den jeweiligen Zweig der Switch-Case zu springen. Nun
benötige ich aber nur zusätzlich einen Zahlenwert. Den wollte ich
zugleich mit dem Zeichen senden --> String. Daher das Format c;01234
Wenn nun eine neue "Anweisung" empfangen wird sollte deer Zweig der
Switch-Case geändert werden.
Bei mir funktioniert der Vergleich nun natürlich nicht mehr, da ich
c_temp (char) mit UART_NO_DATA (int) vergleiche.
Mir fehlt die Idee das jetzt auszubügeln, oder sollte man das ganz
anders angehen?
>char c[0], c_temp[0], num_temp[3];
Du hast sicher nicht in 6 Stunden das C-Buch durchgelesen, die Beispiele
durchgearbeitet und die Aufgaben gelöst.
In den nächsten vier Wochen wollen wir von Dir höchstens Fragen zu einer
Aussage in einem C-Buch, vorzugsweise mit Referenz lesen.
>Du hast sicher nicht in 6 Stunden das C-Buch durchgelesen, die Beispiele>durchgearbeitet und die Aufgaben gelöst.
Falls doch, dann jedenfalls mit dem, angesichts der benötigten Zeit, zu
erwartenden Nicht-Erfolg.
Hmm schrieb:> Du hast sicher nicht in 6 Stunden das C-Buch durchgelesen, die Beispiele> durchgearbeitet und die Aufgaben gelöst.
Das ist wohl wahr.
Aber es steht auch nirgends, dass es verboten ist trotzdem Fragen zu
stellen oder es einfach parallel zu probieren.
Wie gesagt, ich hatte es erst mit einem einzelnen Zeichen realisiert und
es funktionierte, nun benötige ich zusätzlich noch den Zahlenwert als
Parameter für eine weitere Funktion.
>Aber es steht auch nirgends, dass es verboten ist trotzdem Fragen zu>stellen oder es einfach parallel zu probieren.
Da muss ich wohl ein wenig deutlicher werden, da Du so hartleibig bist:
Du wirst gut daran tun, Dir ein gewisses Wohlwollen der Leser hier zu
erhalten. In dem Du aber darauf bestehst, mit einem gewissen Unterton
von nicht abzuweisendem Anspruch, darauf bestehst, uns hier als Vorleser
zu missbrauchen, wirst Du Dir Sympathien verscherzen.
Nun gut. Bei mir hast Du es geschafft. Willkommen in meinem css-File.
Dann noch ein schönes Leben.
Lass mal ansehen, wie du Line definiert hast.
Spätestens nach sowas:
char c[0], c_temp[0], num_temp[3];
hab ich jegliches Vertrauen in irgendwelche Basisvertigkeiten komplett
verloren. Da stimmt hinten und vorne nichts in deinem Code.
> Da ich damit mein Geld nicht verdiene, kann ich mir das ganz gut
verzeihen.
Um das zurecht zu rücken.
Das hat nichts mehr mit 'Geld verdienen' zu tun. Das sind grundlegende
Fertigkeiten, die auch ein Hobby-Programmierer im Schlaf beherrschen
muss. Von einem Profi, der damit seine Brötchen verdient, bist du noch
minestens 4 oder 5 JAHRE Lernzeit entfernt.
Und ich weiß wovon ich rede. Denn ich verdiene damit meine Brötchen.
Du kannst nicht eine Sonntag-Nachmittag Radtour machen, wenn es dich
samt Stützrädern vom Fahrrad schmeißt. Da bist du von Tour de France
noch weit entfernt.
char c[0], c_temp[0], num_temp[3];
war in der Tat etwas vom Sinn befreit. Mittlerweile habe ich es aber zum
Laufen bekommen, indem ich nur die erste Stelle des Strings in c_temp
schreibe und ab der 3. Stelle die ASCII in Int wandle.
Um das mal zurecht zu rücken.
Ich habe nie behauptet damit mein Geld verdienen zu wollen, dass kann
man auch anders ganz gut.
Es ist nur teilweise hier immer wieder das Gleiche, dass eine Frage
gestellt wird und nachdem es nicht gleich nach dem nächsten Posting
läuft sofort draufgehauen wird oder sich einfach mal im Ton vergriffen
wird und man über das Ziel hinaus schießt.
Es hat hier niemand eine fertige Lösung erwartet, mir wurde geholfen,
dafür habe ich mich bedankt, wenn man einmal mehr, mehr oder weniger
sinnbehaftet, nachfragt hat dies nichts mit Undank zu tun. Einen
Unterton hört zudem immer nur der, der ihn hören will, sollte sich aber
auch nicht gleich auf den Schlips getreten fühlen, wenn er ihn selbst
einsetzt.
Ab und an sollte man dochmal die Kirche im Dorf lassen.
Ich denke es hat sich hier niemand, auch ich nicht, im Forum das primäre
Ziel gesetzt das Wohlwollen der Leser zu verscherzen, aber man sollte es
wohl doch alles mit etwas mehr Abstand an der einen oder anderen Stelle
betrachten.
S. Q. schrieb:> Ab und an sollte man dochmal die Kirche im Dorf lassen.
Danke für die Kopfwäsche.
Ich hab daraufhin mal meine Position überdacht und bin zum Schluss
gekommen, dass ich mich in Zukunft etwas mehr raushalten werde, wenn es
um Themen geht von denen ich denke, dass die eigentlich jeder Amateur
können sollte, weil sie in jedem noch so beschissenen C-Buch des langen
und breiten erklärt werden.
Ich seh nämlich auch schon länger nicht mehr ein, warum ich hier als
Erkläronkel fungieren soll, nur weil der Fragesteller wieder mal der
irrigen Meinung ist, er könne C auch einfach so an 2 Nachmittagen lernen
und alle die, die sich 1 Jahr lang durch die Literatur durchgearbeitet
haben und die Dinge von der Pieke auf gelernt haben, wären alles
Weicheier und er brauche das nicht, denn mit den 2 Stück 10-seitigen
Tutorien, die er gelesen hat (wenn überhaupt), wäre alles geklärt.
Nur um mir dann wieder ein ums andere mal sagen lassen zu müssen: "Ich
bin kein Profi, ich muss das nicht können." Nun gut, wenn man der
Ansicht ist, diese Themen wären bereits etwas, was einen Profi von einem
Amateuer unterscheidet, dann soll das so sein. Ich bin da zwar anderer
Ansicht, aber ok. Ein Amateuer sollte meiner Meinung nach den Inhalt vom
K&R beherrschen, zumindest beim Inhalt der ersten Hälfte muss er absolut
sattelfest sein. Vorher ist das nämlich noch nicht mal Amateuer, sondern
die Einstiegsstufe in die absolute Beginnerliga und mit diesem Wissen
anzufangen reale Programme zu schreiben ist viel zu früh. Es ist wie
einen 5-jährigen nach seinem ersten Judo-Trainingsabend auf ein Turnier
zu schicken - absolut sinnlos und der Frust ist vorprogrammiert.
Bei dynamischen Datenstrukturen darf er anfangen zu schwächeln und wenn
es dann um rekursive Algorithmen geht, kann ein Amateur komplett
aussetzen (nicht jedoch ein Profi, für den dürfen Dinge wie Rekursion,
Datenstrukturen, Bäume, Listen, viele Algorithmen, die Idee hinter
Backtracking, eventbasiertes Arbeiten, etc. keine Fremdwörter sein,
genausowenig wie er keine Probleme im strukturellen Aufbau eines
Programms haben darf. Wenn ein Amateuer ein 1000-Zeilen Programm nicht
mehr überblicken kann, dann ist das ok. Für einen Profi liegt die Latte
wesentlich höher - 1000 Zeilen sind da eher eine Fingerübung, die er
problemlos in angemessener Zeit in den Griff kriegen können muss). Für
einen Profi ist der Inhalt vom K&R bzw. die Beherrschung dieses
kompletten(!) Stoffes gerade mal ca. 20% dessen, was er können muss um
als Profi bestehen zu können.
Aber ist ok.
> Danke für die Kopfwäsche.
Sollte keine sein, war auch nicht persönlich gemeint.
> Ich hab daraufhin mal meine Position überdacht und bin zum Schluss> gekommen, dass ich mich in Zukunft etwas mehr raushalten werde, wenn es> um Themen geht von denen ich denke, dass die eigentlich jeder Amateur> können sollte, weil sie in jedem noch so beschissenen C-Buch des langen> und breiten erklärt werden.
Ok.
> Ich seh nämlich auch schon länger nicht mehr ein, warum ich hier als> Erkläronkel fungieren soll
Verlangt auch keiner. Aber es rechnet dir hier jeder hoch an, da du
einer der wenigen bist, die es tun.
> Aber ist ok.
Ist es auch.
Es fühlt sich jeder immer gleich persönlich angegriffen, wenn man mal
etwas zurück schreibt, selber soll man aber immer alles schön schlucken.