2009-07-19 11 views
2

列挙型がユーザー入力によく使用されるかどうかは疑問でした。私のブッククラスでは、フィクション、ノンフィクション、フィクションなどの異なるジャンルの列挙子を使用して列挙型のジャンルを作成する必要があります。列挙型とユーザー入力

ユーザーがプログラムを使用すると、保存されている本の情報。ジャンルについては、通常は文字列関数でこれを行い、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(); 
    } 

(など、書籍を出力、ライブラリに保存します)可能であれば、リストされた列挙子のユーザー入力を受け入れるにはどうすればよいでしょうか?私はGenre変数の作成に沿って何かを考えていました。次に、ユーザがcin >> variableのために入力する関数を持つ。しかし、私は関数が 'fiction'のような入力を理解しておらず、列挙子の値と入力のみを受け入れると推測しています。

答えて

0

Cスタイルの列挙型は、元の文字列名を復元する方法がないため、この目的にはあまり役に立ちません。あなたはいくつかのswitchベースのメカニズムを作ることができます。しかし、その時点では、ユーザーのI/O要件に合うように独自の方法を設定するだけでよいのです。

+0

そこで彼らは唯一の役に立つだろうか? – trikker

+0

うん。私が言及したスイッチベースのメカニズムの一種は、文字列を 'Genre :: whatever'の値で前後に翻訳するためのものです。 – chaos

+0

ええええええ、ありがとうございます。スイッチベースのメカニズムが意味するものの短い擬似コードの例を投稿できますか?私はまだそれが文字列で動作する方法を実際には得られません。 – trikker

0

これを処理する方法の1つは、文字列のマップを列挙型の値に設定することです。他の可能性には、専用機能が含まれる。

いくつかのアイデアについてはquestionを参照してください。

This questionには、列挙型を文字列に変換するコードを生成する方法がいくつかありますが、ほとんどの例は逆も同様に動作します。

1

ジャンルを、列挙型(GenreTypeEnum)をラップするクラスにします。必要な演算子を追加します。 istream、ostream、等価演算子など

ストリームから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; 
    }