Komplettes JSON passt wohl nicht so richtig in einen Mega88/168, aber letzendlich brauch ich das auch gar nicht. Sind auch nur sehr überschaubare Datensätze und leicht auseinander zu puzzeln. Allerdings kommt immer noch bisschen was dazu, und es unterscheidet sich auch von Gerätetyp zu Gerätetyp (RS485-Bus) So funktioniert es bestens, gefällt mir aber nicht. #define RD_cmd 1 #define VER_cmd 2 #define CONFIG_cmd 3 . . . unsigned char parse_command (char * s) {unsigned char command=0; if (!(strncmpf (s, "\"RD\":", 5))) {command=RD_cmd; JsonPtr+=5; } else if (!(strncmpf (s, "\"VER\":", 6))) {... } . . return (command); } Vergleicht also mit s mit <"RD":> (5 Zeichen) und erhöht bei Erfolg JsonPtr um 5. Und genau die magic number 5 ( oder 6, andere sind z.T. noch erheblich länger) sind mein Problem. Lästig und fehleranfällig das abzuzählen.... Ideal wäre, auch den Vergleichsstring per #define anzugeben und der Compiler soll Vergleichslänge/offset selbst auskaspern. Geht das irgendwie?
Gerhard schrieb: > Compiler soll Vergleichslänge/offset selbst auskaspern. Geht das > irgendwie?
1 | static const char MyCommand[] = "Command"; |
2 | static const size_t MyCommandSize = sizeof(MyCommand); |
3 | static const size_t MyCommandLength = sizeof(MyCommand) - 1; // == strlen(MyCommand) |
Damit kannst du alle Magic Numbers erschlagen, auch die Strings selbst. Ich empfehle die Variablen als static zu deklarieren, da ich annehme, dass die Variablen nur in dieser Funktion benötigt werden. Ansonsten werden sie bei jedem Funktionsaufruf neu initialisiert. Die Alternative wäre, die Variablen global zu definieren, evt. auch mit static.
Gerhard schrieb: > Lästig und fehleranfällig das abzuzählen.... Nimm strlen zusammen mit Makro oder Inline-Funktion.
1 | #define strncmpf(S, STR) \
|
2 | strncmp_P (S, PSTR (STR), strlen (STR))
|
3 | |
4 | bool func (const char *str) |
5 | {
|
6 | if (!strncmpf (str, "abc")) |
7 | return true; |
8 | return false; |
9 | }
|
Ein Problem ist, dass es wegen PSTR keine Inline-Funktion sein kann. Evtl. kannst du das dann noch ausbauen so dass str um strlen(...) erhöht wird.
...etwa so in GNU-C99:
1 | #define MATCH(S, STR) \
|
2 | ({ \
|
3 | match_len = strlen (STR); \
|
4 | match = ! strncmp_P (S, PSTR (STR), match_len); \
|
5 | match; \
|
6 | })
|
7 | |
8 | bool func (const char *str) |
9 | {
|
10 | bool match; |
11 | size_t match_len; |
12 | |
13 | if (MATCH (str, "abc")) |
14 | {
|
15 | str += match_len; |
16 | |
17 | if (MATCH (str, "blabla")) |
18 | return true; |
19 | }
|
20 | return false; |
21 | }
|
Makros sind zwar hässlich, aber an dieser Stelle braucht man nur eines...
Be S. schrieb: > Gerhard schrieb: >> Compiler soll Vergleichslänge/offset selbst auskaspern. Geht das >> irgendwie? > static const char MyCommand[] = "Command"; > static const size_t MyCommandSize = sizeof(MyCommand); > static const size_t MyCommandLength = sizeof(MyCommand) - 1; // == > strlen(MyCommand) > Damit kannst du alle Magic Numbers erschlagen, auch die Strings selbst. > Ich empfehle die Variablen als static zu deklarieren, da ich annehme, > dass die Variablen nur in dieser Funktion benötigt werden. Ansonsten > werden sie bei jedem Funktionsaufruf neu initialisiert. Die Alternative > wäre, die Variablen global zu definieren, evt. auch mit static. Perfekt, hätte ich selber drauf kommen können :-) Danke.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.