枚举和用户输入

时间:2009-07-19 02:38:55

标签: c++

我想知道枚举是否通常与用户输入一起使用。我正在做一个练习,在我的Book课程中,我必须创建一个具有不同类型调查员的枚举类型,如小说,非小说等。

当用户使用该程序时,他/她被要求提供有关正在存储的书籍的某些信息。对于一个类型,通常我会用字符串函数执行此操作,并使用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&gt;&gt;变量的功能。但是,我猜测该函数不会理解像'fiction'这样的输入,只会接受枚举器值和输入。

3 个答案:

答案 0 :(得分:1)

Make Genre是一个包装枚举类型的类(GenreTypeEnum)。添加必要的运算符,例如istream,ostream,等于运算符等。

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

答案 1 :(得分:0)

C风格的枚举对于此目的并不十分有用,因为无法恢复原始字符串名称。您可以制作一些基于switch的机制,但此时您也可以设置自己的方式来完成所有与您的用户I / O要求相关的操作,而无需进行操作。

答案 2 :(得分:0)

处理此问题的方法之一是设置字符串映射到枚举值。其他可能性包括专用功能。

有关一些想法,请参阅此question

This question有一些关于如何生成将枚举转换为字符串的代码的想法,但大多数示例也会反过来。