2010-06-10 29 views
30

Tôi muốn sử dụng giá trị enum cho tuyên bố switch. Có thể sử dụng các giá trị enum được đính kèm trong "{}" làm lựa chọn cho số switch() "không? Tôi biết rằng switch() cần giá trị eger int để hướng luồng lập trình đến số case thích hợp. Nếu đây là trường hợp, tôi có tạo ra một biến cho mỗi liên tục trong báo cáo kết quả enum tôi cũng muốn người dùng có thể chọn lựa chọn và thông qua sự lựa chọn đó để báo cáo kết quả switch()làm cách nào để sử dụng giá trị enum trên báo cáo chuyển đổi trong C++

Ví dụ:?.

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

Tất cả các trường hợp đó == 1. –

+8

@Noah: Tôi tin rằng anh ấy đang sử dụng dấu gạch chéo để biểu thị "cái này hay cái kia" chứ không phải phân chia. Trong khi toán học bạn đúng, tôi không tin đó là mã thực tế anh ta định sử dụng. – KevenK

Trả lời

0

đầu vào của người dùng sẽ luôn được cung cấp n cho bạn dưới dạng một chuỗi các ký tự ... nếu bạn muốn chuyển đổi đầu vào của người dùng từ một chuỗi thành một số nguyên, bạn sẽ cần phải cung cấp mã để làm điều đó. Nếu người dùng nhập vào một số (ví dụ: "1"), bạn có thể chuyển chuỗi đó tới atoi() để nhận số nguyên tương ứng với chuỗi. Nếu người dùng nhập chuỗi tiếng Anh (ví dụ: "DỄ DÀNG") thì bạn sẽ cần phải kiểm tra chuỗi đó (ví dụ: với strcmp()) và chỉ định giá trị số nguyên thích hợp cho biến của bạn dựa trên kết quả kiểm tra nào phù hợp. Khi bạn có một giá trị số nguyên được bắt nguồn từ chuỗi đầu vào của người dùng, bạn có thể chuyển nó vào câu lệnh switch() như bình thường.

+2

Mã để chuyển đổi đầu vào từ chuỗi thành số nguyên là 'int i; cin >> i; '. Đây không phải là C, vì vậy không cần phải gây rối với thư viện C. –

28

Bạn có thể sử dụng một giá trị được liệt kê giống như một số nguyên:

myChoice c; 

... 

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

Bạn có thể sử dụng một std::map để lập bản đồ đầu vào cho enum của bạn:

#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

Điều này sẽ trả về 'dễ dàng' nếu chuỗi không khớp với bất kỳ lựa chọn hợp lệ nào. – dreamlax

+0

Tôi thích phương pháp này vì nó cho phép người dùng nhập chuỗi mô tả, không phải số nguyên. Một điều nhỏ, nhưng tôi sẽ sử dụng một bản đồ không có thứ tự cho một cái gì đó với rất ít giá trị có thể. Bản đồ (cây nhị phân) rất thú vị vì nếu có hàng trăm hoặc hàng nghìn giá trị bản đồ sẽ hiệu quả hơn chuyển đổi: trường hợp, chỉ phải thực hiện so sánh O (log N), so với N/2. – RocketRoy

17

Bạn đang đi đúng hướng. Bạn có thể đọc các đầu vào người sử dụng vào một số nguyên và switch trên rằng:

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

Có lẽ nên khởi tạo i đến một giá trị sẽ nhấn trường hợp 'mặc định', hoặc một giá trị được hiểu là lỗi I/O. –

+0

'typedef enum e {...};' ?? Typedef là tùy chọn trong C++ nhưng nếu có, sẽ có một tên typedef-ed sau dấu ngoặc đóng. Ngoài ra, trong C++ (so với C) bạn nên sử dụng kiểu enum và không phải 'int' cho biến (ngay cả khi trình biên dịch sẽ sẵn sàng lấy' int'). –

+0

@Steve: đã đồng ý. Đã cập nhật. –

7

Một số điều cần lưu ý:

Bạn nên luôn luôn tuyên bố enum của bạn bên trong một không gian tên như enums là không gian tên không thích hợp và bạn sẽ bị cám dỗ để sử dụng chúng như một.

Luôn có thời gian nghỉ ở cuối mỗi lần thực thi mệnh đề chuyển đổi sẽ tiếp tục xuống dưới để kết thúc bằng cách khác.

Luôn bao gồm trường hợp default: trong chuyển đổi của bạn.

Sử dụng các biến kiểu enum để giữ giá trị enum cho độ rõ ràng.

xem here để thảo luận về việc sử dụng chính xác các enums trong C++.

Đây là những gì bạn muốn làm.

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

Để làm việc này, bạn sẽ cần phải quá tải toán tử istream '' cho liệt kê. –

+2

+1 tổng thể, nhưng tôi không đồng ý trong trường hợp 'luôn cung cấp mặc định:'. Tôi hiểu rằng ý định được kích hoạt một lỗi đã biết để nó có thể dễ dàng sửa chữa nếu một giá trị mới được liệt kê sau đó được thêm vào điều tra. Tôi thực sự xử lý đầu vào để đảm bảo tính chính xác của dữ liệu người dùng và không cung cấp thẻ 'mặc định', nhưng thay vào đó, trình biên dịch cảnh báo về các câu lệnh chuyển đổi nếu có bất kỳ giá trị nào nằm ngoài tất cả các trường hợp được kiểm tra. Bằng cách này bạn nhận được một báo cáo lỗi nhanh hơn: trình biên dịch sẽ khiếu nại nếu một giá trị được thêm vào liệt kê. –

+0

Ngoài ra bạn có thể cần phải khởi tạo 'enumVar'. Mã này mang lại hành vi không xác định nếu 'cin >> enumVar' không viết một giá trị, thường là trường hợp khi' toán tử >> 'gặp lỗi. Như James nói, mặc dù, bạn sẽ được quá tải các nhà điều hành cho enum anyway, vì vậy bạn có thể viết nó để luôn luôn chỉ định một cái gì đó ngay cả trên lỗi. –

2

tôi đã có một vấn đề tương tự sử dụng enum với trường hợp chuyển đổi sau tôi giải quyết nó trên của riêng tôi .... dưới đây là mã sửa chữa, có lẽ điều này có thể giúp đỡ.

 //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
  • Lưu ý: Tôi biết rằng điều này không trả lời câu hỏi cụ thể này. Nhưng nó là một câu hỏi mà mọi người đến thông qua một công cụ tìm kiếm. Vì vậy, tôi đăng bài này ở đây tin rằng nó sẽ giúp những người dùng.

Bạn nên lưu ý rằng nếu bạn đang truy cập enum tầm cỡ rộng từ chức năng khác ngay cả khi nó là một người bạn, bạn cần phải cung cấp giá trị với một tên lớp:

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

Lưu ý nó như thế nào là PlayingCard::HEARTS và không chỉ là HEARTS.

Các vấn đề liên quan