2010-06-10 62 views
30

Me gustaría utilizar un valor enum para una declaración switch. ¿Es posible utilizar los valores enum incluidos en "{}" como opciones para el switch()? "Sé que switch() necesita un valor de eger para dirigir el flujo de programación al número correspondiente case. Si este es el caso, ¿acabo de hacerlo? hacer una variable para cada constante en la declaración enum también quiero que el usuario sea capaz de recoger la elección y pasar esa elección a la declaración switch()cómo se usa un valor enum en una instrucción switch en C++

por ejemplo:?.

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

Todos esos casos == 1. –

+8

@Noah: Creo que está usando una barra para indicar "uno u otro", no la división. Aunque matemáticamente tienes razón, no creo que ese sea el código real que intenta usar. – KevenK

Respuesta

0

la entrada del usuario siempre se dará n a usted en forma de una cadena de caracteres ... si desea convertir la entrada del usuario de una cadena a un entero, deberá proporcionar el código para hacerlo. Si el usuario escribe un número (por ejemplo, "1"), puede pasar la cadena a atoi() para obtener el número entero correspondiente a la cadena. Si el usuario escribe una cadena en inglés (por ejemplo, "EASY"), deberá verificar esa cadena (por ejemplo, con strcmp()) y asignarle el valor entero apropiado a su variable en función de qué verificación coincida. Una vez que tiene un valor entero derivado de la cadena de entrada del usuario, puede pasarlo a la instrucción switch() como de costumbre.

+2

El código para convertir la entrada de una cadena a un entero es 'int i; cin >> i; '. Esto no es C, así que no hay necesidad de perder el tiempo con la biblioteca C. –

28

puede utilizar un valor enumerado como un entero:

myChoice c; 

... 

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

Puede utilizar un std::map para asignar la entrada a su 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

Esto devolverá 'fácil' si la cadena no coincide con ninguna de las opciones válidas. – dreamlax

+0

Me gusta este enfoque, ya que permite al usuario ingresar cadenas descriptivas, no enteros. Una cosa pequeña, pero usaría un mapa desordenado para algo con tan pocos valores posibles. El mapa (árbol binario) es interesante porque si hubiera cientos o miles de valores, un mapa sería más eficiente que switch: caso, solo tiene que hacer O (log N) se compara, frente a N/2. – RocketRoy

17

Estás en el camino correcto. Usted puede leer la entrada del usuario en un entero y switch en que:

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

Probablemente debería inicializar i a un valor que golpeará el caso 'predeterminado', o un valor interpretado como error de E/S. –

+0

'typedef enum e {...};' ?? El typedef es opcional en C++, pero si está presente, debe haber un nombre typedef-ed después del corchete de cierre. Además, en C++ (en comparación con C) debe utilizar el tipo de enumeración y no 'int' para la variable (incluso si el compilador tomará gustoso' int'). –

+0

@Steve: de acuerdo. Actualizado. –

7

Algunas cosas a tener en cuenta:

Usted debe declarar siempre que su enumeración dentro de un espacio de nombres que las enumeraciones son espacios de nombres no apropiados y se le tentado para usarlos como uno.

Siempre tenga un descanso al final de cada cláusula de conmutación la ejecución continuará hacia abajo hasta el final en caso contrario.

Siempre incluya el estuche default: en su interruptor.

Use variables de tipo enum para mantener los valores enum para mayor claridad.

ver here para una discusión sobre el uso correcto de enums en C++.

Esto es lo que desea hacer.

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

Para que esto funcione, deberá sobrecargar el operador 'istream' 'para la enumeración. –

+2

+1 en general, pero no estoy de acuerdo en el caso 'siempre proporcione un valor predeterminado:'. Entiendo que la intención es desencadenar un error conocido para que pueda corregirse fácilmente si posteriormente se agrega un nuevo valor enumerado a la enumeración. Prefiero realmente procesar la entrada para garantizar la exactitud de los datos del usuario, y no proporcionar una etiqueta 'default', sino hacer que el compilador advierta sobre las declaraciones de cambio si hay algún valor que quede fuera de todos los casos probados. De esta forma se obtiene un informe de error aún más rápido: el compilador se quejará si se agrega un valor a la enumeración. –

+0

También es probable que necesite inicializar 'enumVar'. Este código produce un comportamiento indefinido si 'cin >> enumVar' no escribe un valor, que suele ser el caso cuando' operator >> 'encuentra un error. Sin embargo, como dice James, de todos modos sobrecargarás al operador por la enumeración, de modo que podrías escribirla para asignar siempre algo incluso por error. –

2

que tuve un problema similar usando enumeración con las carcasas de interruptor tarde decidí por mi cuenta .... a continuación es el código corregido, tal vez esto podría ayudar.

 //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
  • Nota: Sé que esto no responde a esta pregunta específica. Pero es una pregunta a la que recurren las personas a través de un motor de búsqueda. Así que estoy publicando esto aquí creyendo que ayudará a esos usuarios.

Usted debe tener en cuenta que si usted está accediendo a la enumeración de toda clase de otra función, incluso si es un amigo, es necesario proporcionar valores con un nombre de clase:

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

Nota cómo es PlayingCard::HEARTS y no solo HEARTS.

Cuestiones relacionadas