Forum: Mikrocontroller und Digitale Elektronik Strtok in C schreibt 0 in Teilstring?


von Bastler (Gast)


Lesenswert?

Hallo zusammen,

ich hab da eine Frage zu Strtok in AVR C. Ich schicke über Uart Strings 
zu einem Atmega 328P, die haben das Format Buchstabe:Zahl also z.B. g:55 
und am Ende ist ein Newline Zeichen \n. Es wird immer nur ein Buchstabe 
geschickt, ein : und eine Zahl nicht größer wie 255.

Im AVR frage ich ab welcher Buchstabe vor dem Doppelpunkt ist, und 
verschiebe dann die Zahl in unterschiedliche Variablen. Schaut so aus 
und funktioniert auch fast :-)

Senden von g:55
1
char deli[] = ":";
2
char input_str[20];
3
uint8_t var1;
4
uint8_t var2;
5
char split1[1];
6
char split2[1];
7
8
if (strcmp(strcpy(split1, strtok(input_str, deli)), "g") == 0)   //Vergleich ob g in split1 drin ist
9
        
10
            {
11
                strcpy(split2, strtok(NULL, deli));   //Inhalt rechts vom Trenner in split2 verschieben
12
                var1 = atoi(split2);  //Inhalt von split2 in Zahl umwandeln und in Variable kopieren
13
                uart_send_string("split1");
14
                uart_send_string(":");
15
                uart_send_number(var1, 10);
16
                uart_send_byte('\n');
17
                input_str[0] = '\0';
18
                split1[0] = '\0';
19
                split2[0] = '\0'; }

Ich hab im Programm direkt darunter das gleiche Konstrukt nochmal drin, 
dieses Mal aber mit der Abfrage ob in split1 ein s drin ist, dann soll 
die Zahl rechts vom : in die Variable var2 geschrieben werden.

Senden von s:66
1
if (strcmp(strcpy(split1, strtok(input_str, deli)), "s") == 0)   //Vergleich ob s in split1 drin ist
2
        
3
            {
4
                strcpy(split2, strtok(NULL, deli));   //Inhalt rechts vom Trenner in split2 verschieben
5
                var2 = atoi(split2);  //Inhalt von split2 in Zahl umwandeln und in Variable kopieren
6
                uart_send_string("split1");
7
                uart_send_string(":");
8
                uart_send_number(var2, 10);
9
                uart_send_byte('\n');
10
                input_str[0] = '\0';
11
                split1[0] = '\0';
12
                split2[0] = '\0'; }

Zur Kontrolle lasse ich mir die aufgetrennten Teilstrings über Uart ans 
Terminal zurückschicken. Beim Vergleich auf "g" schickt der Atmel g:55 
zurück, schaut also ok aus. Beim Vergleich auf "s" schickt der Atmel s:0 
zurück, anstatt s:66...?

Es schaut für mich so aus als ob ich die Syntax richtig kombiniert hab, 
sonst würde ja nicht g:55 zurückkommen, und auch nicht s:0. Also erkennt 
es ja die unterschiedlichen Buchstaben und füllt auch die Zahlen in die 
Variablen, aber hat mir vielleicht jemand einen Hinweis warum bei der 
Strinverarbeitung die im Code weiter unten steht immer 0 im zweiten 
Teilstring ist?

Wenn ich die Bearbeitung von s:66 im Programm VOR der Bearbeitung von 
g:55 einfüge, wird s:66 korrekt über den Uart zurückgeschickt, aber 
dafür zeigt er der denn g:0 an...?

Compilerwarnungen und -fehler gibts keine, ich hab AVR GCC, Makefile und 
Texteditor, und programmiere mit dem Usbasp.

Vielen Dank fürs Lesen.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Steht doch in der Doku, dass strtok da ein Nullzeichen einfügt:
https://www.cplusplus.com/reference/cstring/strtok/
(DIe seite ist auch zu empfehlen für die anderen Funktionen der libc)

Irgendwie muss ja das Ende des Substrings erkannt werden und das 
geschieht in C durch Nullzeichen.

Was du willst ist strpbrk
https://www.cplusplus.com/reference/cstring/strpbrk/
Das gibt nen Pointer auf das erste gefundene ':' und NULLt nix.
Atio bricht ja eh ab sobald was anderes als ein Zahlzeichen kommt.

von Sebastian (Gast)


Lesenswert?

split1 und split2 sind nur 1 Byte gross?

LG, Sebastian

von Bastler (Gast)


Lesenswert?

Hallo,

Mw E. schrieb:
> Was du willst ist strpbrk

Super jetzt gehts so wie es soll vielen Dank! Wochenende gerettet ;-)

Sebastian schrieb:
> split1 und split2 sind nur 1 Byte gross?

Ja das langt doch für einzelne Buchstaben oder Zahlen bis 255 oder 
nicht?

Gruß

von Rolf M. (rmagnus)


Lesenswert?

Bastler schrieb:
> Sebastian schrieb:
>> split1 und split2 sind nur 1 Byte gross?
>
> Ja das langt doch für einzelne Buchstaben oder Zahlen bis 255 oder
> nicht?

Für einzelne Buchstaben ja, aber nicht für einen String, der einen 
Buchstaben enthält, weil der noch nullterminiert ist und dafür ein 
zusätzliches Byte benötigt. Dieses zusätzliche Byte wird auch von strcpy 
da rein kopiert, also schreibst du damit über das Ende des Arrays 
hinaus.

von Sebastian (Gast)


Lesenswert?

Bastler schrieb:
> Ja das langt doch für einzelne Buchstaben oder Zahlen bis 255 oder
> nicht?

... und wie sollen da all die Zeichen '2' '5' '5' '\0' reinpassen?

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.