2009-07-19 83 views
2

我在想如果枚舉通常與用戶輸入一起使用。我正在做一個練習,在我的Book類中,我必須用不同類型的枚舉數創建enum類型,例如小說,非小說等。枚舉和用戶輸入

當用戶使用該程序時,他/她被要求確定關於正在存儲的書籍的信息。對於一個流派,通常我只是用一個字符串函數來做這件事,並用if語句將它限制在某些名字上。

但是,我不知道如何用枚舉類型完成相同的過程,也不知道它是否應該用於這類事情。如果你有興趣,這裏是代碼。那些沒有被目前使用的一些事情,因爲該功能他們是尚未完全沒有實現的一部分

#include "std_lib_facilities.h" 

//Classes----------------------------------------------------------------------- 

class Book{ 
public: 
     Book(){}; // default constructor 
     //operators 
     friend ostream& operator<<(ostream& out, const Book& val); 
     bool Book::operator==(const Book& check) 
     //enumerators 
     enum Genre{ 
      fiction, nonfiction, periodical, biography, children}; 
     //member functions 
     string title(); 
     string author(); 
     int copyright(); 
     void ISBN(); 
     bool checkout(); 
private: 
     string title_; 
     string author_; 
     int copyright_; 
     int ISBN1; 
     int ISBN2; 
     int ISBN3; 
     char ISBN4; 
     bool checkout_; 
}; 

// Error Function--------------------------------------------------------------- 

void _error(const string& s) 
{ 
    cout << endl; 
    cout << "Error: " << s << endl; 
    cout << endl; 
} 

// Member Functions------------------------------------------------------------- 

string Book::title() 
{ 
     cout << "Title: "; 
     getline(cin,title_); 
     cout << endl; 
     return title_; 
} 

string Book::author() 
{ 
     cout << "Author: "; 
     getline(cin,author_); 
     cout << endl; 
     return author_; 
} 

int Book::copyright() 
{ 
    cout << "Copyright: "; 
    cin >> copyright_; 
    cout << endl; 
    return copyright_; 
} 

void Book::ISBN() 
{ 
    cout << "ISBN (Use spaces): "; 
    cin >> ISBN1 >> ISBN2 >> ISBN3 >> ISBN4; 
    if((ISBN1<0) || (ISBN2<0) || (ISBN3<0) || (ISBN1>9) || (ISBN2>9) || (ISBN3)>9) 
       _error("Must be single digit."); 
    else if(!isdigit(ISBN4) && !isalpha(ISBN4)) 
       _error("Must be single digit or letter."); 
    else{ cout << endl; 
      return;} 
} 

bool Book::checkout() 
{ 
    char check; 
    cout << "Checked out?(Y or N): "; 
    cin >> check; 
    switch(check){ 
    case 'Y': 
      cout << endl; 
      return true; 
      break; 
    case 'N': 
      cout << endl; 
      return false; 
      break; 
    default: 
       _error("Must be Y or N.");} 
} 

// Operator Overloads----------------------------------------------------------- 

ostream& operator<<(ostream& out, const Book& val){ 
     out << "Title: " << val.title_ << endl; 
     out << "Author: " << val.author_ << endl; 
     out << "ISBN: " << val.ISBN1 << "-" << val.ISBN2 << "-" << val.ISBN3 << "-" << val.ISBN4 << endl; 
     out << endl; 
     return out;} 

bool Book::operator==(const Book& check){ 
    return((ISBN1 == check.ISBN1) && (ISBN2 == check.ISBN2) && (ISBN3 == check.ISBN3) 
      && (ISBN4 == check.ISBN4));} 

// Main------------------------------------------------------------------------- 

int main() 
{ 
    bool finished = false; 
    char notfinished; 
    while(!finished) 
    { 
     Book book; 
     book.title(); 
     book.author(); 
     book.copyright(); 
     book.ISBN(); 
     book.checkout(); 
     cout << "Do you wish to store another book?(Y or N): "; 
     cin >> notfinished; 
     if(notfinished == 'Y'){ 
        cin.ignore(); 
        cout << endl;} 
     else if(notfinished == 'N') finished = true; 
     else _error("Must be Y or N"); 
     } 
    keep_window_open(); 
    } 

注意(在庫中存儲,輸出圖書等)

那麼,如果可能的話,接受用戶對所列舉的統計員的輸入需要什麼?我正在考慮製作一個流派變量。然後有一個用戶輸入cin >>變量的函數。但是,我猜這個函數不會理解像'fiction'這樣的輸入,只會接受枚舉器的值和輸入。

回答

0

C樣式枚舉對於這個目的不是非常有用,因爲沒有辦法恢復原始字符串名稱。你可以製造一些基於switch的機制,但是在這一點上,你可能只是設置你自己的方式來完成這一切與你的用戶I/O需求一起工作,而沒有鞋楦。

+0

所以會如果我直接在程序中通過傳遞參數存儲數據,如書(類型小說::),他們僅是有用的? – trikker 2009-07-19 02:51:30

0

處理此問題的方法之一是設置字符串映射以枚舉值。其他可能性包括專用功能。

看到這個question的一些想法。

This question對如何生成代碼來將枚舉轉換爲字符串有一些想法,但大多數示例也會反向工作。

1

使Genre成爲包裝枚舉類型(GenreTypeEnum)的類。添加必要的操作員,例如istream,ostream,equal operator等。

在istream運算符中,可以從流中讀取std :: string,然後解析並將值轉換爲關聯的GenreTypeEnum。

像這樣的東西可能:

namespace GenreType { enum GenreTypeEnum { miscellaneous, fiction, non_fiction, children }; } 

    class Genre 
    { 
     public: 
     Genre() : genreType(GenreType::miscellaneous) {} 
     ~Genre() {} 

     void setType(std::string genreTypeString){ // implement string-> enum } 
     std::string toString(void) const { // convert genre back to string } 

     private: 

     GenreType::GenreTypeEnum genreType; 

    }; 

    std::ostream& operator<<(std::ostream& os, const Genre& genre) 
    { 
     os << genre.toString(); 
     return os; 
    } 

    std::istream& operator>>(std::istream& is, Genre& genre) 
    { 
     std::string input; 
     is >> input; 

     genre.setType(input); 
     return is; 
    }