Problem bei Variablenlänge bei sscanf
-
Hallo,
ich habe mit unterem Code folgendes Problem, aus dem String Command sollen zwei Zahlen (0-255) mit Komma getrennt extrahiert werden und in Level[0] + Level[1] gespeichert werden. Das klappt auch soweit, nur wird irgendwie die Variable die als nächstes im Speicher steht mit 0x00 überschrieben was zu Fehlern führt.
Ich vermute, da ich ja die Speicheradresse übergebe das Level[0 und 1] jeweils mit 2 Bytes (short) anstatt 1 Byte (char) geschrieben werden und es somit zu einem "Speicherplatzüberlauf" kommt der die nächste Variable im Speicher "beschädigt".Wie kann ich dem Compiler sagen das er nur 1Byte (char) extrahiert?
if (2 == sscanf(Command, "%3d,%3d", *(char *)&Level[0], *(char *)&Level[1])) {funktioniert nicht.
volatile unsigned char Level[] = {0,0}; void main(void) { if (2 == sscanf(Command, "%3d,%3d", &Level[0], &Level[1])) { .... } }
-
%d
erwartet als Argument einenint
eger und schreibt auch einen.
Was Du suchst ist%hhu
.
-
Hat leider nicht geklappt, ich programmiere einen Mikrocontroller in C, vielleicht kennt er &hhu nicht?
Habe %3hhu und %hhu probiert und jedes mal macht der MC hinter dem sscanf Befehl einen Reset bzw. schmiert ab.
Gibt es noch eine andere Möglichkeit?
-
@Jackson00 lies in 2 ints und weis dann hinterher den chars diese zu.
-
Ich habe nur 4K RAM! auf dem MC würde ich ungern machen...
-
Dieser Beitrag wurde gelöscht!
-
Aber dann sscanf verwenden mit formatstring etc...
-
Probier als erstes mal aus, ob es funktioniert, wenn du C99 anmachst. Denn das wirst du wahrscheinlich vergessen haben, und es bestehen gute Chancen, dass deine Umgebung das beherrscht. Denn aus jenem Standard ist
%hhu
. Falls nicht funktioniert: Tja? Du wirst ja wohl Platz für einen temporärenint
auf dem Stack haben, wenn du schon eine fette Funktion wie scanf nutzt.
-
@SeppJ sagte in Problem bei Variablenlänge bei sscanf:
eine fette Funktion wie scanf nutzt.
wenn du auf die Formatprüfung (das Komma, unsigned char Überlauf,...) verzichten kannst, weil der String immer korrekt formatiert ist, reicht auch 2x atoi, also in etwa
x = atoi(string); y = atoi(strchr(string,',')+1);
-
@SeppJ sagte in Problem bei Variablenlänge bei sscanf:
Probier als erstes mal aus, ob es funktioniert, wenn du C99 anmachst. Denn das wirst du wahrscheinlich vergessen haben, und es bestehen gute Chancen, dass deine Umgebung das beherrscht. Denn aus jenem Standard ist
%hhu
. Falls nicht funktioniert: Tja? Du wirst ja wohl Platz für einen temporärenint
auf dem Stack haben, wenn du schon eine fette Funktion wie scanf nutzt.Wie kann ich das an machen? Compiler Setting?
Ich nutze diesen aus:
https://www.cypress.com/documentation/software-and-drivers/tool-lineup-f2mc-16-family-softune-v3Und den sscanf Befehl nutze ich schon mehrmals in dem Programm und auch diverse male für 1Byte Zahlenumwandlung (0-255)
-
@Jackson00 sagte in Problem bei Variablenlänge bei sscanf:
Wie kann ich das an machen? Compiler Setting?
Soweit ich gesehen habe unterstützt das Ding maximal C89. Ein
int
mehr oder weniger am Stack bringt dich nicht um. Sonst siehe @Wutz' Vorschlag.
-
@Jackson00 Kannst du das hier runterladen (erfordert einen Login)?
Ansonsten für eine evtl. ältere Version:
The compiler described in this manual conforms to the American National Standard for
Information Systems ⎯ Programming Language C, X3.159-1989, which is abbreviated as
"ANSI standard" in this manual.
-
Dieser Beitrag wurde gelöscht!
-
Dieser Beitrag wurde gelöscht!
-
Wenn ich das jetzt richtig verstanden habe kann C89 das nicht sondern erst c99 und es gibt keine Möglichkeit unter dieser Version mit sscanf eine Zahl als char aus einem String zu extrahieren. Nur als int.
Der String könnte leider auch Übertragungsfehler haben deswegen wäre atoi nicht die Wahl.
Dann wäre wirklich die einzige Möglichkeit sscanf mit temporären Int-Varialblen auszulesen und dann später in die eigentlichen char Variablen zu schreiben, richtig?
-
@Jackson00 sagte in Problem bei Variablenlänge bei sscanf:
Dann wäre wirklich die einzige Möglichkeit
sscanf()
mit temporären int-Varialblen auszulesen und dann später in die eigentlichen char Variablen zu schreiben, richtig?Ja. Die beiden
int
egers sind sowieso Funktionslokal auf dem Stack und wieder weg sobald der Scope verlassen wird. Wie gesagt, wird Dich nicht umbringen.
-
Das mit den int wäre auch sicherer, da %hhu UB ist, falls du doch mal probierst, Werte >255 damit einzulesen (bei CHAR_BIT=8).
-
Würde dann so in etwa aussehen?
unsigned short tmp1, tmp2; if (2 == sscanf(Command, "%3d,%3d", &tmp1, &tmp2)) { Level[0] = (*(char *) &tmp1); Level[1] = (*(char *) &tmp2); }
-
@Jackson00
Oh Gott, hilf - natürlich nicht so.unsigned tmp1, tmp2; if (2 == sscanf(Command, "%u,%u", &tmp1, &tmp2)) { Level[0] = (unsigned char)tmp1; Level[1] = (unsigned char)tmp2; }
evtl. noch testen, ob tmp >255 ist.
-
@Jackson00 sagte in Problem bei Variablenlänge bei sscanf:
Würde dann so in etwa aussehen?
Nein!
%d ist für int
%hd ist für short
%hu ist für unsigned short