Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluate a string with a switch in C++ [duplicate]

Tags:

c++

I want to evaluate a string with a switch but when I read the string entered by the user throws me the following error.

#include<iostream> using namespace std;      int main() {         string a;         cin>>a;         switch (string(a)) {         case "Option 1":             cout<<"It pressed number 1"<<endl;             break;         case "Option 2":             cout<<"It pressed number 2"<<endl;             break;         case "Option 3":             cout<<"It pressed number 3"<<endl;             break;         default:             cout<<"She put no choice"<<endl;             break;         }         return 0;     } 

error: invalid cast from type 'std::string {aka std::basic_string}' to type 'int

like image 321
Alejandro Caro Avatar asked May 05 '13 19:05

Alejandro Caro


People also ask

Can a switch statement evaluate a string?

The switch statement compares the String object in its expression with the expressions associated with each case label as if it were using the String. equals method; consequently, the comparison of String objects in switch statements is case sensitive.

Can you use a switch statement with strings in C?

The expression in the switch statement can be any valid expression which yields an integral value. The expression can also be a character constant ( because all characters are eventually converted to an integer before any operation ) but it can't be floating point or string.

Can switch case have duplicates?

If two cases in a 'switch' statement are identical, the second case will never be executed. This most likely indicates a copy-paste error where the first case was copied and then not properly adjusted.

Can switch take two arguments in C?

Yes, this is valid, because in this case, the , is a comma operator. The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.


2 Answers

As said before, switch can be used only with integer values. So, you just need to convert your "case" values to integer. You can achieve it by using constexpr from c++11, thus some calls of constexpr functions can be calculated in compile time.

something like that...

switch (str2int(s)) {   case str2int("Value1"):     break;   case str2int("Value2"):     break; } 

where str2int is like (implementation from here):

constexpr unsigned int str2int(const char* str, int h = 0) {     return !str[h] ? 5381 : (str2int(str, h+1) * 33) ^ str[h]; } 

Another example, the next function can be calculated in compile time:

constexpr int factorial(int n) {     return n <= 1 ? 1 : (n * factorial(n-1)); }    int f5{factorial(5)}; // Compiler will run factorial(5)  // and f5 will be initialized by this value.  // so programm instead of wasting time for running function,  // just will put the precalculated constant to f5  
like image 51
Serhiy Avatar answered Sep 21 '22 14:09

Serhiy


You can map the strings to enum values, then switch on the enum:

enum Options {     Option_Invalid,     Option1,     Option2,     //others... };  Options resolveOption(string input);  //  ...later...  switch( resolveOption(input) ) {     case Option1: {         //...         break;     }     case Option2: {         //...         break;     }     // handles Option_Invalid and any other missing/unmapped cases     default: {         //...         break;     } } 

Resolving the enum can be implemented as a series of if checks:

 Options resolveOption(std::string input) {     if( input == "option1" ) return Option1;     if( input == "option2" ) return Option2;     //...     return Option_Invalid;  } 

Or a map lookup:

 Options resolveOption(std::string input) {     static const std::map<std::string, Option> optionStrings {         { "option1", Option1 },         { "option2", Option2 },         //...     };      auto itr = optionStrings.find(input);     if( itr != optionStrings.end() ) {         return itr->second;     }     return Option_Invalid;  } 
like image 40
mskfisher Avatar answered Sep 17 '22 14:09

mskfisher