Оценить строку с помощью переключателя на С++
Я хочу оценить строку с помощью переключателя, но когда я прочитал строку, введенную пользователем, я нахожу следующую ошибку.
#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
Ответы
Ответ 1
Как уже говорилось, коммутатор может использоваться только с целыми значениями. Таким образом, вам просто нужно преобразовать ваши значения "case" в integer. Вы можете достичь этого, используя constexpr из С++ 11, поэтому некоторые вызовы функций 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
Ответ 2
Оператор A switch
может использоваться только для целых значений, а не для значений пользовательского типа. И даже если это возможно, ваша операция ввода также не работает.
Вам может понадобиться следующее:
#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.
Ответ 3
Вы можете использовать только тип switch-case для типов, применимых к int.
Однако вы можете определить std::map<std::string, std::function> dispatcher
и использовать его как dispatcher[str]()
для достижения такого же эффекта.
Ответ 4
Вы можете сопоставить строки с значениями перечисления, затем включить перечисление:
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;
}
return Option_Invalid;
}
Ответ 5
а как же просто номер опции:
#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;
}
Ответ 6
Вы не можете. Полная остановка.
switch
предназначен только для целых типов, если вы хотите разветкиться в зависимости от строки, которую вы должны использовать if/else
.
Ответ 7
Значение переключателя должно иметь тип Integral. Кроме того, поскольку вы знаете, что дифференцирующий символ находится в положении 7
, вы можете включить a.at(7)
. Но вы не уверены, что пользователь ввел 8 символов. Возможно, он допустил ошибку ввода. Поэтому вы должны окружить свой оператор switch в Try Catch. Что-то с этим ароматом
#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
.
ИЗМЕНИТЬ
Извлечение 7-го символа с помощью operator[]()
не выполняет проверку границ, поэтому поведение будет undefined. мы используем at()
из std::string
, который проверяется границами, как описано здесь.