2010-06-10 7 views
30

Je souhaite utiliser une valeur enum pour une instruction switch. Est-il possible d'utiliser les valeurs enum enfermées dans "{}" comme choix pour le switch() « ? Je sais que switch() a besoin d'une valeur int eger afin de diriger le flux de la programmation au nombre case approprié. Si tel est le cas, est-ce que je viens faire une variable pour chaque constante dans la déclaration enum Je veux aussi à l'utilisateur de pouvoir choisir le choix et passer ce choix à la déclaration switch()Comment utiliser une valeur enum sur une instruction switch en C++

par exemple:.

cout << "1 - Easy, "; 
cout << "2 - Medium, "; 
cout << "3 - Hard: "; 

enum myChoice { EASY = 1, MEDIUM = 2, HARD = 3 }; 

cin >> ???? 

switch(????) 
{ 
case 1/EASY: // (can I just type case EASY?) 
    cout << "You picked easy!"; 
    break; 

case 2/MEDIUM: 
    cout << "You picked medium!"; 
    break; 

case 3/HARD: // ..... (same thing as case 2 except on hard.) 

default: 
    return 0; 
} 
+3

Tous ces cas == 1. –

+8

@Noah: Je crois qu'il utilise une barre oblique pour indiquer "l'un ou l'autre", pas la division. Bien que mathématiquement vous ayez raison, je ne crois pas que ce soit le code qu'il a l'intention d'utiliser. – KevenK

Répondre

0

l'entrée de l'utilisateur sera toujours donner n à vous sous la forme d'une chaîne de caractères ... si vous voulez convertir l'entrée de l'utilisateur d'une chaîne en un entier, vous devrez fournir le code pour le faire. Si l'utilisateur tape un nombre (par exemple "1"), vous pouvez passer la chaîne à atoi() pour obtenir l'entier correspondant à la chaîne. Si l'utilisateur tape une chaîne en anglais (par exemple "EASY") alors vous devrez vérifier cette chaîne (par exemple avec strcmp()) et affecter la valeur entière appropriée à votre variable en fonction de laquelle cocher correspond. Une fois que vous avez une valeur entière dérivée de la chaîne d'entrée de l'utilisateur, vous pouvez le passer dans l'instruction switch() comme d'habitude.

+2

Le code pour convertir l'entrée d'une chaîne en un entier est 'int i; cin >> i; '. Ce n'est pas C, donc il n'y a pas besoin de déranger avec la bibliothèque C. –

28

Vous pouvez utiliser une valeur énumérée comme un entier:

myChoice c; 

... 

switch(c) { 
case EASY: 
    DoStuff(); 
    break; 
case MEDIUM: 
    ... 
} 
6

Vous pouvez utiliser une carte std::map pour l'entrée à votre enum:

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

enum level {easy, medium, hard}; 
map<string, level> levels; 

void register_levels() 
{ 
    levels["easy"] = easy; 
    levels["medium"] = medium; 
    levels["hard"] = hard; 
} 

int main() 
{ 
    register_levels(); 
    string input; 
    cin >> input; 
    switch(levels[input]) 
    { 
    case easy: 
     cout << "easy!"; break; 
    case medium: 
     cout << "medium!"; break; 
    case hard: 
     cout << "hard!"; break; 
    } 
} 
+0

Cela retournera 'easy' si la chaîne ne correspond à aucun des choix valides. – dreamlax

+0

J'aime cette approche car elle permet à l'utilisateur d'entrer des chaînes descriptives, pas des nombres entiers. Une petite chose, mais j'utiliserais une carte non ordonnée pour quelque chose avec si peu de valeurs possibles. La carte (arbre binaire) est intéressante car s'il y avait des centaines ou des milliers de valeurs une carte serait plus efficace que switch: cas, il suffit de comparer O (log N) vs N/2. – RocketRoy

17

Vous êtes sur la bonne voie. Vous pouvez lire l'entrée d'utilisateur dans un entier et switch sur ce point:

enum Choice 
{ 
    EASY = 1, 
    MEDIUM = 2, 
    HARD = 3 
}; 

int i = -1; 

// ...<present the user with a menu>... 

cin >> i; 

switch(i) 
{ 
    case EASY: 
    cout << "Easy\n"; 
    break; 
    case MEDIUM: 
    cout << "Medium\n"; 
    break; 
    case HARD: 
    cout << "Hard\n"; 
    break; 
    default: 
    cout << "Invalid Selection\n"; 
    break; 
} 
+0

Doit probablement initialiser i à une valeur qui atteindra le cas par défaut, ou une valeur interprétée comme une erreur d'E/S. –

+0

'typedef enum e {...};' ?? Le typedef est optionnel en C++ mais s'il est présent, il devrait y avoir un nom typedef-ed après l'accolade fermante. De même, en C++ (par rapport à C), vous devriez utiliser le type enum et non 'int' pour la variable (même si le compilateur accepte volontiers' int'). –

+0

@Steve: accepté. Actualisé. –

7

Quelques choses à noter:

Vous devez toujours déclarer votre ENUM dans un espace de noms que les énumérations ne sont pas appropriés namespaces et vous serez tentés pour les utiliser comme un.

Toujours avoir une pause à la fin de chaque clause de l'exécution de la clause de commutation continuera vers le bas jusqu'à la fin sinon.

Toujours inclure le boîtier default: dans votre commutateur.

Utilisez des variables de type enum pour conserver les valeurs enum pour plus de clarté. Voir here pour une discussion sur l'utilisation correcte des énumérations en C++.

C'est ce que vous voulez faire.

namespace choices 
{ 
    enum myChoice 
    { 
     EASY = 1 , 
     MEDIUM = 2, 
     HARD = 3 
    }; 
} 

int main(int c, char** argv) 
{ 
    choices::myChoice enumVar; 
    cin >> enumVar; 
    switch (enumVar) 
    { 
     case choices::EASY: 
     { 
      // do stuff 
      break; 
     } 
     case choices::MEDIUM: 
     { 
      // do stuff 
      break; 
     } 

     default: 
     { 
      // is likely to be an error 
     } 
    }; 

} 
+0

Pour que cela fonctionne, vous devez surcharger l'istream 'operator >>' pour l'énumération. –

+2

+1 globalement, mais je ne suis pas d'accord dans le cas 'always provide default:'. Je comprends que l'intention déclenche une erreur connue afin qu'elle puisse être facilement corrigée si une nouvelle valeur énumérée est ajoutée plus tard à l'énumération. Je préfère réellement traiter l'entrée pour garantir l'exactitude des données de l'utilisateur, et ne pas fournir de balise 'default', mais plutôt demander au compilateur d'avertir à propos des instructions switch s'il y a une valeur qui tombe en dehors de tous les cas testés. De cette façon, vous obtenez un rapport d'erreur encore plus rapide: le compilateur se plaindra si une valeur est ajoutée à l'énumération. –

+0

Vous devez également initialiser 'enumVar'. Ce code génère un comportement indéfini si 'cin >> enumVar' n'écrit pas de valeur, ce qui est généralement le cas lorsque' operator >> 'rencontre une erreur. Comme le dit James, cependant, vous surchargez l'opérateur pour l'énumération de toute façon, de sorte que vous pouvez l'écrire pour toujours attribuer quelque chose, même en cas d'erreur. –

2

i eu un problème similaire en utilisant ENUM avec les interrupteurs plus tard, je résolus par moi-même .... ci-dessous est le code corrigé, peut-être cela pourrait aider.

 //Menu Chooser Programe using enum 
    #include<iostream> 
    using namespace std; 
    int main() 
    { 
     enum level{Novice=1, Easy, Medium, Hard}; 
     level diffLevel=Novice; 
     int i; 
     cout<<"\nenter a level: "; 
     cin>>i; 
     switch(i) 
     { 
     case Novice: cout<<"\nyou picked Novice\n"; break; 
     case Easy: cout<<"\nyou picked Easy\n"; break; 
     case Medium: cout<<"\nyou picked Medium\n"; break; 
     case Hard: cout<<"\nyou picked Hard\n"; break; 
     default: cout<<"\nwrong input!!!\n"; break; 
     } 
     return 0; 
    } 
0
#include <iostream> 
using namespace std; 

int main() { 

    enum level {EASY = 1, NORMAL, HARD}; 

    // Present menu 
    int choice; 
    cout << "Choose your level:\n\n"; 
    cout << "1 - Easy.\n"; 
    cout << "2 - Normal.\n"; 
    cout << "3 - Hard.\n\n"; 
    cout << "Choice --> "; 
    cin >> choice; 
    cout << endl; 

    switch (choice) { 
    case EASY: 
     cout << "You chose Easy.\n"; 
     break; 
    case NORMAL: 
     cout << "You chose Normal.\n"; 
     break; 
    case HARD: 
     cout << "You chose Hard.\n"; 
     break; 
    default: 
     cout << "Invalid choice.\n"; 
    } 

    return 0; 
} 
2
  • Note: Je ne sais que cela ne répond pas à cette question précise. Mais c'est une question que les gens viennent à travers un moteur de recherche. Donc je publie ceci ici en pensant que cela va aider ces utilisateurs.

Vous devez garder à l'esprit que si vous accédez à ENUM de classe à l'échelle d'une autre fonction, même si elle est un ami, vous devez fournir des valeurs avec un nom de classe:

class PlayingCard 
{ 
private: 
    enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }; 
    int rank; 
    Suit suit; 
    friend std::ostream& operator<< (std::ostream& os, const PlayingCard &pc); 
}; 

std::ostream& operator<< (std::ostream& os, const PlayingCard &pc) 
{ 
    // output the rank ... 

    switch(pc.suit) 
    { 
    case PlayingCard::HEARTS: 
     os << 'h'; 
     break; 
    case PlayingCard::DIAMONDS: 
     os << 'd'; 
     break; 
    case PlayingCard::CLUBS: 
     os << 'c'; 
     break; 
    case PlayingCard::SPADES: 
     os << 's'; 
     break; 
    } 
    return os; 
} 

Notez comment est PlayingCard::HEARTS et pas seulement HEARTS.

Questions connexes