Evalueer een string met een schakelaar in C++

Ik wil een string evalueren met een schakelaar, maar wanneer ik de string lees die door de gebruiker is ingevoerd, krijg ik de volgende foutmelding.

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

fout: ongeldige cast van type ‘std::string {aka std::basic_string}’ naar ‘int


Antwoord 1, autoriteit 100%

Zoals eerder gezegd, kan schakelaar alleen worden gebruikt met gehele waarden. U hoeft dus alleen uw “case” -waarden naar een geheel getal om te zetten. U kunt dit bereiken door constexpruit c++11 te gebruiken, dus sommige oproepen van constexpr-functies kunnen worden berekend tijdens het compileren.

zoiets…

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

waar str2int is (implementatie van hier):

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

Nog een voorbeeld, de volgende functie kan worden berekend in compileertijd:

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 

Antwoord 2, Autoriteit 36%

U kunt de strings naar ENUM-waarden in kaart brengen en vervolgens de ENUM inschakelen:

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

Het oplossen van de ENUM kan worden geïmplementeerd als een reeks ifcontroles:

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

of een kaart-opzoeken:

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

Antwoord 3, Autoriteit 22%

A switchVerklaring kan alleen worden gebruikt voor integrale waarden, niet voor waarden van door de gebruiker gedefinieerde type. En zelfs als het zou kunnen, werkt uw invoeroperatie niet, ook.

Mogelijk wilt u dit:

#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.

Antwoord 4, Autoriteit 16%

U kunt alleen schakelaars gebruiken op typen die gieten aan een INT.

U kunt echter een std::map<std::string, std::function> dispatcheren gebruik het als dispatcher[str]()om hetzelfde effect te bereiken.


Antwoord 5, Autoriteit 5%

Hoe zit het met het optie-nummer:

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

Antwoord 6, Autoriteit 3%

je kunt het niet. Volledige stop.

switchis alleen voor integrale typen, als u wilt filiaalen, afhankelijk van een reeks die u moet gebruiken if/else.


Antwoord 7

Switchwaarde moet een Integraal-type hebben. Omdat u weet dat het onderscheidende teken op positie 7staat, kunt u a.at(7)ook inschakelen. Maar u weet niet zeker of de gebruiker 8 tekens heeft ingevoerd. Hij kan net zo goed een typefout hebben gemaakt. Dus je moet je switch-statement omringen met een Try Catch. Iets met deze smaak

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

De standaardclausule in de switch-instructie legt gevallen vast waarin gebruikersinvoer minimaal 8 tekens lang is, maar niet in {1,2,3}.

Als alternatief kunt u waarden inschakelen in een enum.

BEWERKEN

Het 7e teken ophalen met operator[]()voert geen grenscontrole uit, zodat het gedrag ongedefinieerd zou zijn. we gebruiken at()van std::string, dat is gecontroleerd, zoals hier uitgelegd.

Other episodes