C-String unbestimmte Länge
-
Hallo!
ich mache für mein Programm ein kleine Kommandozeile, nun habe ich das Problem, dass ich in den Befehlen Leerzeichen benötige, also verwende ich fgets. fgets fordert eine bestimmte Länge, nur, ich kann das nicht pauschal angeben: Mal ist die Zeichenkette nur z.B. /?\0 und mal /help\0, also ganz verschieden. Wenn ich z.B. für /help\0 die Zahl 6 für 6 Zeichen nehme, dann findet strcmp zwar /help und alle anderen Befehle mit Zeichenlänge 6, aber /? nicht mehr.Code:
int GetCommand() { static char command[103]; printf("$ > "); fgets(command, strlen(command), stdin); if(!strcmp(command, "/?") || !strcmp(command, "/help")) PrintHelp(); if(!strcmp(command, "/exit") || !strcmp(command, "/close")) return 1; if(!strcmp(command, "/n") || !strcmp(command, "/new")) printf("%s", command); return 0; }
Ist diese ewige if(!strcmp()erei "elegant"? Gibt es schönere Lösungen, die gleichzeitig mein Problem lösen?
-
Achso, das strlen da war nur ein verzweifelter Versuch, nicht beachten!
-
Mauli schrieb:
Ist diese ewige if(!strcmp()erei "elegant"? Gibt es schönere Lösungen, die gleichzeitig mein Problem lösen?
ein array mit char*, das du absuchst z.b. und dann den index zurückgibts. weil's immer zwei kommandos sind, die das gleiche bedeuten, kannst du z.b. den index immer durch 2 teilen, etwa so:
int find_cmd (char *cmd) { static char *cmds[] = {"hallo1", // 0 "hallo2", // auch 0 "doof1", // 1 "doof2", // auch 1 "blah1", // 2 "blah2"}; // auch 2 int s; for (s=0; s<sizeof(cmds)/sizeof(*cmds); s++) { if (strcmp(cmd, cmds[s]) == 0) return s/2; } return -1; // not found }
-
> weil's immer zwei kommandos sind, die das gleiche bedeuten, kannst du z.b. den index immer durch 2 teilen, etwa so:
Und was bringt das? Ich muss ja dem Command irgendwie die jeweilige Funktion zuweisen, was hilft dort ein halber Index der Cmds-Liste?
-
Mauli schrieb:
Und was bringt das? Ich muss ja dem Command irgendwie die jeweilige Funktion zuweisen, was hilft dort ein halber Index der Cmds-Liste?
das ersetzt dein: if(!strcmp(command, ...) || !strcmp(command, ...))
wenn's anders ist, also nur ein string pro kommando, dann natürlich nicht.
-
ach hier, so gehts noch einfacher:
#include <stdio.h> #include <string.h> // funktionen für die kommandos void doof (void){puts ("doof");} void hallo (void){puts ("hallo");} void blah (void){puts ("blah");} // liste der funktionen und keywords struct cmds { char *name; void (*func)(void); }cmds[] = { "hallo1", hallo, "hallo2", hallo, "doof1", doof, "doof2", doof, "blah1", blah, "blah2", blah, // einfach andere kommandos anhaengen }; // funktion anhand des namens aufrufen void call_cmd (char *cmd) { int s; // suchen... for (s=0; s<sizeof(cmds)/sizeof(*cmds); s++) { // gefunden? --> dann aufrufen if (strcmp(cmd, cmds[s].name) == 0) { cmds[s].func(); } } } // test void main () { call_cmd ("hallo1"); call_cmd ("gibts_nicht"); call_cmd ("blah2"); }
-
Das ist eine sehr schöne Lösung, ich bin zu viel C++ gewöhnt, kann kein C.
Meine Funktion schaut so aus:
int GetCommand() { struct CmdTable { const char *name; void (*func)(void); } cmds[] = { "/?", PrintHelp, "/help", PrintHelp }; static char command[103]; printf("$ > "); fgets(command, 3, stdin); int i; for(i = 0; i < sizeof(cmds) / sizeof(*cmds); i++) { if(strcmp(command, cmds[i].name) == 0) { cmds[i].func(); } } return 0; }
Aber noch wichtiger ist mir: wie kann ich dieses C-String-Problem lösen? Ich habe a) Leerzeichen, die ich haben MUSS und b) ist die Stringlänge verschieden, sodass ich in fgets keine Längenangabe machen kann.
-
ich bin zu viel C++ gewöhnt, kann kein C
mein reden. c++ verdirbt den character. *grins*
Mauli schrieb:
Ich habe a) Leerzeichen, die ich haben MUSS
wieso muss? und wenn, fgets() liest doch leerzeichen mit ein, oder nicht?
ausserdem kannst du den string doch nach belieben weiterverarbeiten, leerzeichen hinzufügen, abschneiden, usw.Mauli schrieb:
b) ist die Stringlänge verschieden, sodass ich in fgets keine Längenangabe machen
mach einfach ein array, das gross genug ist, um den längsten befehl zu fassen. dessen länge und adresse übergibste dann an fgets().
-
Mauli schrieb:
int GetCommand() { static char command[103]; printf("$ > "); fgets(command, strlen(command), stdin); if(!strcmp(command, "/?") || !strcmp(command, "/help")) PrintHelp(); if(!strcmp(command, "/exit") || !strcmp(command, "/close")) return 1; if(!strcmp(command, "/n") || !strcmp(command, "/new")) printf("%s", command); return 0; }
In Zeile 4 benutzt du strlen, aber command wurde noch nicht initialisiert, d.h. da kann alles mögliche oder auch nix drin stehen. Warum benutzt du nicht sizeof()?