将string用于switch语句(c++做C#的事儿, switch中break还是return厉害)
作为一个C++程序员,或是出于习惯,或是出于无奈,你多少次这么写:
if (!strcmp(pszValue, "Value X"))
DoThis();
else if (!strcmp(pszValue, "Value Y"))
DoThat();
else if (!strcmp(pszValue, "Value Z"))
DoSomethingElse();
else
DontKnowWhatToDo();
你千百次的问,如果这个时候可以使用switch多好呢?
switch(strValue)
{
case "Value X":
DoThis();
break;
case "Value Y":
DoThat();
break;
case "Value Z";
DoSomethingElse();
break;
default:
DontKnowWhatToDo();
break;
上面这段代码在C Sharp中是合法的,但是作为一个C++程序员,你只能无奈和无奈。
下面就是用enum和std::map完成这个愿望!
#include <map>
#include <string>
#include <iostream.h>
// Value-Defintions of the different String values
static enum StringValue { evNotDefined,
evStringValue1,
evStringValue2,
evStringValue3,
evEnd };
// Map to associate the strings with the enum values
static std::map<std::string, StringValue> s_mapStringValues;
// User input
static char szInput[_MAX_PATH];
// Intialization
static void Initialize();
int main(int argc, char* argv[])
{
// Init the string map
Initialize();
// Loop until the user stops the program
while(1)
{
// Get the user's input
cout << "Please enter a string (end to terminate): ";
cout.flush();
cin.getline(szInput, _MAX_PATH);
// Switch on the value
switch(s_mapStringValues[szInput])
{
case evStringValue1:
cout << "Detected the first valid string." << endl;
break;
case evStringValue2:
cout << "Detected the second valid string." << endl;
break;
case evStringValue3:
cout << "Detected the third valid string." << endl;
break;
case evEnd:
cout << "Detected program end command. "
<< "Programm will be stopped." << endl;
return(0);
default:
cout << "'" << szInput
<< "' is an invalid string. s_mapStringValues now contains "
<< s_mapStringValues.size()
<< " entries." << endl;
break;
}
}
return 0;
}
void Initialize()
{
s_mapStringValues["First Value"] = evStringValue1;
s_mapStringValues["Second Value"] = evStringValue2;
s_mapStringValues["Third Value"] = evStringValue3;
s_mapStringValues["end"] = evEnd;
cout << "s_mapStringValues contains "
<< s_mapStringValues.size()
<< " entries." << endl;
}
这里有个特别重要的技巧,那就是为什么把enumeration的第一个设为evNotDefined ?
首先我们要明确std::map::operator[] 的作用: 1 设置一个key的value 2 取值。这个时候需要注意,若不存在,才会被插入。
即程序中对于s_mapStringValues,如果szInput 是新的,将会被插入。 并且 the value默认为0 。 如果enumeration第一项为evStringValue1,任何一个未知的string value 都会导致一个有效的switch case。所以我们才这么干。
============================================================== 这里还有个小问题 讨论一下,就是switch语句中return厉害还是break厉害: 代码:
switch(s_mapStringValues[szInput])
{
case evStringValue1:
cout << "Detected the first valid string." << endl;
return 0;//还会执行break吗?
break;
case evStringValue2:
cout << "Detected the second valid string." << endl;
break;
case evStringValue3:
cout << "Detected the third valid string." << endl;
break;
case evEnd:
cout << "Detected program end command. "
<< "Programm will be stopped." << endl;
return(0);
default:
cout << "'" << szInput
<< "' is an invalid string. s_mapStringValues now contains "
<< s_mapStringValues.size()
<< " entries." << endl;
break;
}
测试,表面,return了 就不会break了。