Task: the user enters commands, the program executes them. Wanted to use switch , but he doesn’t want to handle a variable like string , only int .
Here is some of the code:
while (command == "NULL")
{
cout & lt; & lt; '& gt;';
cin & gt; & gt; command;
}
if (command == "exit")
{
exit = 1;
}
if (command == "map")
{
view_map (map, POLE);
}
if (command == "goto")
{
string direction;
int steps;
cin & gt; & gt; direction & gt; & gt; steps;
if (steps & lt; 0)
cout & lt; & lt; "And what about yours?" & lt; & lt; endl;
if (direction == "left")
HeroCoord_x = HeroCoord_x - steps;
if (direction == "right")
HeroCoord_x = HeroCoord_x + steps;
if (direction == "up")
HeroCoord_y = HeroCoord_y - steps;
if (direction == "down")
HeroCoord_y = HeroCoord_y + steps;
if ((HeroCoord_x & lt; 0) || (HeroCoord_x & gt; POLE) || (HeroCoord_y & lt; 0) || (HeroCoord_y & gt; POLE))
{
cout & lt; & lt; "Nipalusaitsanah!" & lt; & lt; endl;
if (direction == "left")
HeroCoord_x = HeroCoord_x + steps;
if (direction == "right")
HeroCoord_x = HeroCoord_x - steps;
if (direction == "up")
HeroCoord_y = HeroCoord_y + steps;
if (direction == "down")
HeroCoord_y = HeroCoord_y - steps;
}
else
{
make_map (map, POLE);
go_to (map, HeroCoord_x, HeroCoord_y);
}
}
Answer 1, authority 100%
You can make handler mapping and use it.
Something like:
struct Handler {
void handle () = 0;
virtual ~ Handler () {}
};
struct ExitHandler: public Handler {
void handle () {
// code here
}
};
struct MapHandler: public Handler {
void handle () {
// code here
}
};
struct GotoHandler: public Handler {
void handle () {
// code here
}
};
// =====================
std :: map & lt; std :: string, Handler * & gt; handlers;
handlers ["exit"] = new ExitHandler ();
handlers ["goto"] = new GotoHandler ();
handlers ["map"] = new MapHandler ();
// -----------------------
while (command == "NULL")
{
cout & lt; & lt; '& gt;';
cin & gt; & gt; command;
}
handlers [command] - & gt; handle ();
Answer 2, authority 93%
String-to-number mapping can be used:
std :: map & lt; std :: string, int & gt; mapping;
mapping ["left"] = LEFT;
mapping ["up"] = UP;
mapping ["right"] = RIGHT;
mapping ["down"] = DOWN;
switch (mapping [command]) {
case LEFT: doLeft (); break;
case UP: doUp (); break;
case RIGHT: doRight (); break;
case DOWN: doDown (); break;
}
Answer 3, authority 100%
If you are not afraid of collisions, then you can use constexpr
functions from C++ 11, and do switch
by hashes of strings.
// FNV-1a hash, 32-bit
inline constexpr std :: uint32_t fnv1a (const char * str, std :: uint32_t hash = 2166136261UL) {
return * str? fnv1a (str + 1, (hash ^ * str) * 16777619ULL): hash;
}
int main () {
std :: string s = "bb";
switch (fnv1a (s.c_str ())) {
case fnv1a ("a"): std :: cout & lt; & lt; "A \ n"; break;
case fnv1a ("bb"): std :: cout & lt; & lt; "B \ n"; break;
case fnv1a ("ccc"): std :: cout & lt; & lt; "C \ n"; break;
};
}
Answer 4
- command == “map” – does it work? Interesting to know how. You are comparing pointers, but you need to compare strings, for this there is the strcmp function (or can the == operator be overloaded for char * by default? I am something off topic 🙂
-
When I was solving a similar problem, I simply wrote a function and put the lines into an array:
const char * protoCommands [] = { "AUTH", "REG", "ADDPT", "ACCPT", "GETPTS", "GETSTATE", "DISC" }; const int protoSize = sizeof (protoCommands) / sizeof (char *); / * ... * / int switchFunc (char * buf) { for (int i = 0; i & lt; protoSize; ++ i) if (! strcmp (buf, protoCommands [i])) return i; return -1; } / * ... * / switch (switchFunc (buf)) { ... }