Hallo!
Ich möchte, dass der Controller die Werte eines Strings einem Variablen-
Array korrekt zuweist.
Der String setzt sich aus Teistrings zusammen, die mit Semikolon
getrennt sind. Ein Teilstring ist mit Doppelpunkt getrennt.
Stringbeispiel: 1:54;3:23;8:45
Daraus soll folgen, dass
receive_value[1] 54,
receive_value[3] 23 und
receive_value[8] 45 annimmt.
Mein Code dazu funktioniert, allerdings habe ich das Gefühl dass der
ziemlich aufgebläht ist- Stringfunktionen sollen ja recht mühsam sein.
Ich weiss aber nicht wie ich ihn optimieren kann. Weiß wer Rat?
mach alles in einem Aufwasch, ohne zuerst die Teilstrings in ein
getrenntes String Array umzukopieren.
Du darfst bei strtok durchaus auch abwechselnd verschiedene Trenner
benutzen
1
...
2
3
ptr=strtok(uart_string,":");
4
while(ptr)
5
{
6
// jetzt haben wir den "Index" -> in eine Zahlumwandeln
7
index=atoi(ptr);
8
ptr=strtok(NULL,";");
9
if(ptr)
10
{
11
// und jetzte auch noch den zugehörigen Wert
12
wert=atoi(ptr);
13
receive_value[index]=wert;
14
}
15
16
ptr=strtok(NULL,":");
17
}
18
}
sieht doch schon gleich viel kürzer aus und ist auch sicherer, weil du
nicht gefahr läufst, bei den strcpy die Zielstrings zu überlaufen.
Und 400 Bytes SRAM sparst du obendrein :-)
verlagert die Verantwortung für das Einhalten der Arraygrenzen auf das
Programm, das die Strings sendet. Geht da irgendetwas daneben, wird
irgendwo wild in den RAM geschrieben.
Tom K. schrieb:> Geht da irgendetwas daneben...
D.h., wenn StringvonAussen = "100", foo aber nur 50 Elemente groß ist,
schwappts über, gell?
Wie umgehen? Einfache if-Abfrage?
nur mit strtol
Stephan schrieb:> Stringbeispiel: 1:54;3:23;8:45>> Daraus soll folgen, dass> receive_value[1] 54,> receive_value[3] 23 und> receive_value[8] 45 annimmt.
Stephan schrieb:> Tom K. schrieb:>> Geht da irgendetwas daneben...>>> D.h., wenn StringvonAussen = "100", foo aber nur 50 Elemente groß ist,> schwappts über, gell?> Wie umgehen? Einfache if-Abfrage?
:-)
Ja, die einfachsten Dinge sind oft die besten.
Stephan schrieb:> chris schrieb:>> unsigned char>> parse(char*str) { unsigned char ret;>> do {>> idx=strtol(str,&str,0); // oder 10 fuer dec>> while(*str++==':') {>> val=strtol(str,&str,0); // oder 10 fuer dec>> if(idx>=0&&idx<sizeof(receive_value)/sizeof(receive_value[0]))>> receive_value[idx++]=val,ret++;>> }>> } while(*str++==';');>> return ret;>> }>> Da muss man erstmal hinterkommen.....
halb so wild.
strtol vereint mehr oder weniger ein atoi und das strtok in einer
Funktion.
atoi würde selbsttätig mit dem Konsumieren des Strings aufhören, sobald
etwas nicht mehr zur Zahl gehört.
D.h. wirfst du atoi das hier vor
"123:56"
dann konsumiert atoi alles bis zum ':'.
Soweit so gut. Nur weißt du nicht, wo im String diese Aufhören
stattfindet, so dass du das nächste atoi 1 Zeichen dahinter ansetzen
könntest.
und genau da kommt strtol ins Spiel. Es liefert dir genau diese
Position, bis zu der es aus dem String Zeichen konsumiert hat. Mit
dieser Position (nach Prüfung natürlich) kannst du dann den nächsten
strtol dahinter ansetzen, der wieder alles was nach Zahl aussieht
konsumiert und dir mit dem Pointer bekannt gibt, wo dieses Ende war.
Woraufhin du dort den nächsten strtol ansetzt, etc. etc.
Stephan schrieb:> schwappts über,
Programme werden zuverlässiger, wenn man solche Eingaben von Anfang an
als potentiell falsch oder bösartig betrachtet ;)