string a;
cin>>a;
switch (a)
{
case "b":
break;
}
🔒 Locked
"switch" problem
Advertisement
Original Post
I'm trying to check "string a"'s value by means of a switch statement: However, error: "switch expression of type 'std::string' is illegal". But I really need that I can be able to check strings. So: 1) how can I solve my string-in-switch problem? I can't make "a" anything but string! 2) Why can't C++ programmers be smart and make "switch" accept anything? I thought they were smart...
Quote:
Original post by asdqwe
1) how can I solve my string-in-switch problem? I can't make "a" anything but string!
You could use a std::map, using std:string as the key and function pointers as the value. Essentially you'd be making a jump table similar to what a switch statement would do.
Quote:
Original post by asdqwe
2) Why can't C++ programmers be smart and make "switch" accept anything? I thought they were smart...
Possibly because in early versions of C++ there was no std::string and the standard hasn't been updated to accept them in switches.
Quote:
Original post by asdqwe
2) Why can't C++ programmers be smart and make "switch" accept anything? I thought they were smart...
I assume you're talking about the people who write the compiler.
They are bound by the language standard. It's possible, but it goes against the language philosophy. A switch statement is not simply checking the variable against every listed value one at a time. It could compile into a jump table or other such things. There's also the whole backwards compatibility thing. And if they made it accept char*, for example, (and if you accept ints and std::string instances, why not accept *any* type?) people would expect the code to do string comparison (via strcmp() or whatever) for that particular type, and it would be an ugly special case. Unless there were some way to specify the comparison method, but that would require changing the language grammar.
Do you need to use switch for some reason? If not, you can just use if/else instead:
string a; cin>>a; if(a=="b") { // Do something } else if(a=="c") { // Do something else } // etc.Quote:
Original post by asdqwe
To RebNyx: I need to check the whole string a, not only a[0].
why? If you're checking for word comparison (ie does input=="apple", why not use something like strcmp() ?
otherwise, if they're all flags and you wanted to check char by char...
for(int i = 0; i < strLength ; ++i){switch(data){case 'a':break;case 'b':break;//...}}Quote:
2) Why can't C++ programmers be smart and make "switch" accept anything? I thought they were smart...
It's works only with simple integral types (ie. numbers (char and enum are numbers too) because the C++ commitee thinks that's enough. :P
Think of it, two char*s could be compared by the string they are pointing too or address. Which one should be chosen by the compiler? You had to add some _more_ special syntax to the language, and that's not worth it. And when you work with std::strings or user-defined string types, it gets even more complicated.
The C++ mantra is "don't pay what you don't need". You can hand-tune C++ code to your liking, and that's why the language provides mostly "primitive" facilities because you can code everything you need with these, optimized to the last bit if you need (eg. in inner rendering loops, you can achieve near-assembly performance).
To adress your problem, you can use if else or you can disguise it in macros if you really want.
It takes some time to get used to proper C++.
Quote:For very short short strings (four to eight characters or so) you can treat the whole string as a single long integer and switch on that. Another possibility is to use a perfect hash function on the string and switch on the that instead, though unless the input string is guaranteed to be one in the set you'll still need a single strcmp at the end to verify the result.
Original post by asdqwe
Thanks for the info but still- what can I do now? I'm sure I've seen methods of managing strings (and char's) via "switch", w/o std::map - only not in a direct way. But I can't remember how it was done!
Of course such techniques are aimed towards improving performance, not simplifying things.
An if-else construct would work just fine for this. Switch is for integral types.
To Smitty1276 & all:
OK, I'd better make it clearer. What I'm trying to do is make a fun little game that accepts as input (stored in the infamous 'string a', see 1st post) people's names. And each name once inputted leads to calling a *different* function, fitting perfectly in the 'switch' architecture. So: >Pete --> do_a(); >Steve --> do_b(); etc.
That's why I need for switch to accept strings or char*'s: 'cause these names can be stored only in strings or char*'s, right?
Or can you see another way?
OK, I'd better make it clearer. What I'm trying to do is make a fun little game that accepts as input (stored in the infamous 'string a', see 1st post) people's names. And each name once inputted leads to calling a *different* function, fitting perfectly in the 'switch' architecture. So: >Pete --> do_a(); >Steve --> do_b(); etc.
That's why I need for switch to accept strings or char*'s: 'cause these names can be stored only in strings or char*'s, right?
Or can you see another way?
Some people already suggested using if/else, why do you persist on the switch thing?
Simply put: You CANNOT do this using switch. Also, i don't see a point in making map and pointers to functions, i really don't know why some people are even suggesting it, because it's just over-complicated solution for such trivial problem... That's like a lot more code for nothing, because from what i understand flexibility isn't the case here.
Simply put: You CANNOT do this using switch. Also, i don't see a point in making map and pointers to functions, i really don't know why some people are even suggesting it, because it's just over-complicated solution for such trivial problem... That's like a lot more code for nothing, because from what i understand flexibility isn't the case here.
#include <iostream>#include <string>using namespace std;void do_a(){}void do_b(){}void do_c(){}int main(){ cout << "Type your name: "; string name; cin >> name; if(name == "Jack"){ do_a(); cout << "Jack is cool\n"; } else if (name == "Peter") { do_b(); cout << "Peter is smart\n"; } else if (name == "Samantha"){ do_c(); cout << "Samantha is pretty\n"; } return 0;}Quote:
Original post by asdqwe
To Smitty1276 & all:
OK, I'd better make it clearer. What I'm trying to do is make a fun little game that accepts as input (stored in the infamous 'string a', see 1st post) people's names. And each name once inputted leads to calling a *different* function, fitting perfectly in the 'switch' architecture. So: >Pete --> do_a(); >Steve --> do_b(); etc.
No, switch isn't useful for this in any real-world scenario. The only time switch is used for tasks like this is in context of security disasters where people do things like that for authentication of web sites. Stuff like:
switch (request.getParameter("username")) { case "Admin" : set_cookie("admin", "true"); break; case "Joe" : set_cookie("admin", "false"); break;};But any non-trivial application has no use for this.
The reason lies elsewhere:
Switch operates on compile-time constants, and string values are typically something that is best not hard-coded. Although some languages allow switch over strings and other types, C++ does it right and forbids it.
Second thing to consider is the functions you're calling. Why is there a function for each name? What does this function do?
One reason where this comes handy is for scripting, where you need to resolve function name into some invocation - again, a completely different approach is used there.
But this is really nothing more than problem statement clarification. In any realistic scenario there will be no need to switch between hard-coded set of strings and hard-coded set of functions in this way.
Quote:
That's why I need for switch to accept strings or char*'s: 'cause these names can be stored only in strings or char*'s, right?
Or can you see another way?
What are you actually trying to do? What are do_a() and do_b()? What is the purpose of application?
So far, all possible syntactic options have been explained, the only way to provide some other constructive advice is to try to actually solve the problem, and not fight with the language syntax anymore.
Quote:
Why can't C++ programmers be smart and make "switch" accept anything
They are smart. Not allowing non-integral types is a "good thing".
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement