switch mit strings?
-
hallo zusammen,
ich habe gerade ein kleines Problem:
Ich frage mir in einer Client/Server-Appliakation per recv(...) eine Nachricht ab, die ich dann in einem char* buffer drin stehen hab und die immer sozusagen aus codes besteht. Und jetzt würde ich am liebsten sowas machen:
switch(buffer) { case "CODE 1": bla case "CODE 2": bla ... }
Bisher ist mir nur
if(strcmp(buffer, "CODE 1") bla; else if(strcmp(buffer, "CODE 2") bla; else if(...) ...
eingefallen, aber das ist ja nicht gerade effizient hoch 10. Hat jemand ne bessere Idee?
-
so ein else-if konstrukt kann recht lang werden, bevor es sich lohnt, über andere methoden nachzudenken. die grundsätzliche antwort lautet dann "verwende eine map". die idee bei der verwendung einer map ist dabei schlicht, die notwendigen string vergleiche unter O(n) zu drücken.
für deine anwendung würd es sich wahrscheinlich lohnen, sich eine methode zu basteln, die die strings in switch-bare typen wandelt. ints als op-code z.b. dann muss das ganze nur einmal gemacht werden und für die weitere verwendung ist man die strings los.
-
ja so ähnlich hab ich mir das auch schonmal überlegt, aber dann müsste ich da doch trotzdem wieder alle strings vergleichen.
Es gibt zwar in meinem Fall jetzt nur 6 verschiedene Nachrichten, von denen auch jeweils der erste Buchstabe verschieden ist (das könnte man ja für die switch-Anweisung nutzen) aber ich möchte halt überprüfen, ob das Wort ganz eingelesen wurde und INIT 123 nicht das gleiche macht wie INSELAFFE 123, aber auch dafür muss ich wieder alle einzeln vergleichen...
-
switch auf einen string müsste auch alle strings vergleichen, du würdest dabei nichts gewinnen.
wie wärs damit:
const char* KEYWORDS[] = { "foo", "bar", "baz", NULL }; enum KEYCODES = { UNKNOWN = -1, FOO, BAR, BAZ }; int string2code(const char* codestr) { /* über alle keywords iterieren und mit codestr vergleichen */ /* rückgabe: index im KEYWORDS-array, UNKNOWN bei fehler */ const char** word = KEYWORDS; while(*word) { if(!strcmp(*word, codestr)) return word - KEYWORDS; ++word; } return UNKNOWN; }
(ungetestet, möglicherweise fehlerhaft, nur zur veranschaulichung)
dann kannst du schreiben:
switch(string2code(codestr)) { case FOO : ... case BAR : ... }
wenn bestimmte keywords häufiger erwartet werden als andere, packst du sie an den anfang des arrays. wenn es viele keywords werden, könntest du sie alphabetisch sortieren und mit binärer suche hantieren.
-
geniale Idee, da wär ich nie drauf gekommen.
Vielen Dank
-
viel effizienter wäre es, wenn dein server
mit zahlen antworten würde ( 1, 2, usw )
anstelle mit zeichenketten
( "Code 1", "Code 2", usw. )