用 C + + 中的开关计算字符串

我想用一个开关来计算一个字符串,但是当我读取用户输入的字符串时,会出现以下错误。

#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: 从类型‘ std: : string { aka std: : basic _ string }’到类型‘ int 的转换无效

351934 次浏览

switch语句只能用于整数值,而不能用于用户定义类型的值。(即使可以,您的输入操作也不能正常工作。>>操作提取单个标记,用空格分隔,因此它永远不能检索值 "Option 1"。)

你可能想要这个:

#include <string>
#include <iostream>




std::string input;


if (!std::getline(std::cin, input)) { /* error, abort! */ }


if (input == "Option 1")
{
// ...
}
else if (input == "Option 2")
{
// ...
}


// etc.

不行,句号。

switch仅适用于整数类型,如果您希望根据字符串进行分支,则需要使用 if/else

只要有一个选择号码怎么样:

#include <iostream>
#include <string>
using namespace std;


int main()
{
string s;
int op;


cin >> s >> op;
switch (op) {
case 1: break;
case 2: break;
default:
}


return 0;
}

您可以将字符串映射到枚举值,然后打开枚举:

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;
}
}

解析枚举可以实现为一系列 if检查:

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

或者查找地图:

 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;
}

开关值必须具有 Integral 类型。此外,由于您知道区分字符是在位置 7,您可以打开 a.at(7)。但是您不能确定用户输入了8个字符。他也可能打错了字。因此,您需要将 switch 语句包围在 Trycatch 中。有这种味道的东西

#include<iostream>
using namespace std;
int main() {
string a;
cin>>a;


try
{
switch (a.at(7)) {
case '1':
cout<<"It pressed number 1"<<endl;
break;
case '2':
cout<<"It pressed number 2"<<endl;
break;
case '3':
cout<<"It pressed number 3"<<endl;
break;
default:
cout<<"She put no choice"<<endl;
break;
}
catch(...)
{


}
}
return 0;
}

Switch 语句中的默认子句捕获用户输入至少为8个字符的情况,但不包括{1,2,3}中的情况。

或者,您可以在 enum中打开值。

剪辑

使用 operator[]()获取第7个字符不执行边界检查,因此行为将是未定义的。我们使用来自 std::stringat(),它是边界检查的 就像这里解释的那样。

如前所述,开关只能用于整数值。因此,您只需要将“ case”值转换为整数即可。可以通过使用 c + + 11中的 Constexpr来实现,因此可以在编译时计算一些 Constexpr 函数的调用。

诸如此类。

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

Str2int 类似于(从 给你实现) :

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

另一个例子,下一个函数可以在编译时计算出来:

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

对于类型可浇铸为 int 的类型,只能使用 switch-case。

但是,您可以定义一个 std::map<std::string, std::function> dispatcher,并像使用 dispatcher[str]()一样使用它来达到同样的效果。