Click to See Complete Forum and Search --> : using null terminated strings with switch/case
ikk
September 28th, 2005, 08:55 AM
how can i use strings inside switch block in c/c++,
what macro i must create to make folowing code work?
#define CMD_1 "cmd 1"
#define CMD_2 "cmd 2"
Function( char* command )
{
switch(command){
case CMD_1:
...
break;
case CMD_2:
...
break;
}
}
Marc G
September 28th, 2005, 08:58 AM
You can't. A switch can only be used on itegral types. You should use a bunch of if statements for your case.
cilu
September 28th, 2005, 09:24 AM
Well, if you want that, switch to C#. (the pun was intended :D)
Hobson
September 28th, 2005, 09:29 AM
When actions for each option are enclosed within separate functions rather than in single 'case block' maybe creating a map of strings to function pointers would be good idea. Basically it would be pretty the same, but it maybe would make your code clearer (if there is a lot of options, and not only 2).
Unfortunately, as Marc said, 'switch' is useful only for integral types.
Hob
ikk
September 28th, 2005, 10:04 AM
Well, if you want that, switch to C#. (the pun was intended :D)
i know what u mean :) , but id rather stay with regular c and use if-elseif set.
SuperKoko
September 28th, 2005, 10:42 AM
If it is C++ code, you can use a std::map<std::string, AnotherType>.
Here are the types you can use for AnotherType:
A pointer to an abstract base class containing at least one ExecCommand virtual method, but maybe a more complex interface, depending on your projects.
A pointer to a function (which executes the command).
An integer.
This integer can be used as an identifier in a switch statement.
Use this solution, only if the switch clauses, really need the local variables and data of the function.
But, you probably want to code that in C.
In that case, you can try to emulate a std::map class (maybe with a less performant algorithm), or write your own hash table.
If performance is not an issue, or if there are very few switch clauses, you can even use an array of structures (each structure contains a const char* and a pointer to function, or identifier).
wschweit
September 28th, 2005, 10:51 AM
If you don't have very many commands to keep track of you could do something like this:
#define CMD_1 1
#define CMD_2 2
#define SWITCH(x) switch( (strcmp(x,"cmd 1") == 0) ? 1 : \
(strcmp(x ,"cmd 2") == 0) ? 2 : \
0)
void Function( char* command )
{
SWITCH(command){
case CMD_1:
break;
case CMD_2:
break;
}
}
NMTop40
September 28th, 2005, 11:13 AM
There is no such language as C/C++.
You either want to write it in C or in C++.
If programming in C++, I'd generally recommend SuperKoko's first method but it's more complex than it appears.
In order to use the polymorphism, you'll need a map from string to pointers to different implementations of an abstract base class. (The virtual method doesn't have to called ExecCommand).
How you'd set this map up and where it belongs will depend on your overall design. In particular, how the instances of these abstract classes are created, and how they are destroyed. If they have no data members then I'd recommend making global instances. Globals should generally be avoided though for any classes that have data members (thread-safety issues, for one. hidden side-effects, etc). You might want instances in the class that contains the map, or a special class that has the map and the instances.
Finally, you might want to create them on the heap, in which case they'd have to be deleted at some point. If you use that approach, you'll want to use reference-counted pointers or COW-pointers.
SuperKoko
September 28th, 2005, 01:22 PM
wschweit: your code is wrong :
== compares pointers and not the strings.
Instead, you should use strcmp.
And instead of using an ugly macro, it is preferable to use a function:
unsigned StringToCommandID(const char *cmd)
{
if (strcmp(cmd,"cmd 1")==0) return 1;
else if (strcmp(cmd,"cmd 2")==0) return 2;
else return 0;
}
And remember that this approach is only acceptable if there are very few cases.
In other cases, you should at least put the associations between strings and integers, in a container; at least a C-style array of structures, if you program in C, or a std::map with the method NMTop40 described if you program in C++
wschweit
September 28th, 2005, 01:44 PM
yes, strcmp is the correct way to compare, my bad. Too used to c++ std::strings.
A function is the most maintainable, but the macro makes your code easier to read in this case.
std::map is definately the best way to go though.
Your code is wrong too! doesn't distinguish between 1 and 2. ;)
SuperKoko
September 28th, 2005, 02:09 PM
Your code is wrong too! doesn't distinguish between 1 and 2.
:D
right, i edited it!
wschweit
September 28th, 2005, 02:50 PM
Fixed mine too in case someone tried to use it. It worked when I tried it before I posted...
ikk
September 29th, 2005, 03:50 PM
thanx for the ideas, maybe ill try to figure out something with map class
stober
September 29th, 2005, 04:01 PM
There is no such language as C/C++.
You either want to write it in C or in C++.
That's what it means in American English :) But I can understand how it can be confusing to non-Americans or others not accustomed to reading gobbledegook. :D
RoboTact
September 29th, 2005, 04:18 PM
You can also use enum for integer ID and populate map with pairs <string, id>. It's better for cases when you need just few of whole list (but more then 2-3 cases). When number of cases is big enough (about 5 or more), switch block would become messy and it would be better to use distinct functions/functors. And don't use those null terminated arrays, use strings instead.
NMTop40
September 30th, 2005, 05:24 AM
Also remember extensibility. Will the list ever be extended and in how many places would you have to update if it were? Is it possible to extend without modifying any existing code at all?
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.