Strtok in C schreibt 0 in Teilstring?

Gast #6703010
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.
(Firma: fritzler-avr.de) #6703028
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.
#6703093
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 5 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.