Получение входных данных из cin для нескольких перечислений в структуре в c ++ - PullRequest
2 голосов
/ 06 января 2020

Вот мой код:

enum Color {red, blue};
enum Number {3,4};
enum Shape {circle, square};

struct article 
{
    enum Color color;
    enum Number number;
    enum Shape shape;
} article_1;

//assume I have the below for all three enums
std::istream& operator>>( std::istream& is, Color& I ) 
{
    int tmp ;
    if ( is >> tmp )
        i = static_cast<Color>( tmp ) ;
    return is ;
}

int main ()
{
    cout<<"Enter the Color : ";
    cin>>article_1.color;

    cout<<"Enter the Number : "; 
    cin>>article_1.number;

    cout<<"Enter the Shape : ";
    cin>>article_1.shape;

    return 0;
}

Код компилируется без ошибок. Тем не менее, когда появляется всплывающее окно с просьбой ввести цвет, при вводе красного цвета оно исчезает, и я получаю сообщение об ошибке Program.exe has exited with code 0(0x0). Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 06 января 2020

перечисления являются функцией уровня компиляции . После того, как приложение скомпилировано, появляются только цифры. Строки, которые вы вводите в перечисление, заменяются числами во время запуска программы.

Вам нужно будет скопировать строку и сравнить ее со строкой runtime (не перечислением) чтобы получить то, что вам нужно.

std::string x;
cin >> x;
if (x == "red") 
{
}

Вы также можете создать std::map<std::string,int>. комментарий от scohe001 также показывает некоторые способы.

0 голосов
/ 07 января 2020

В C ++ нет интеллектуального преобразования между строками и перечислениями.

Ваш входной код не работает, потому что вы читаете int из входного потока и приводите его к цвету:

  • Это может сработать, если вы введете действительное целое число, соответствующее одной из кодировок значений перечисления.
  • Но если вы введете строку, операция ввода завершится неудачно из-за несовместимого типа. Входной поток получает ошибку, и все последующие операции в этом потоке будут терпеть неудачу, пока вы не очистите флаги ошибок.

Если вы хотите прочитать строку, вам нужно позаботиться об этом. Например, со следующим кодом:

std::istream& operator>>( std::istream& is, Color& I ) 
{
    std::string tmp;
    if ( is >> tmp ) {
        for (auto&c:tmp)
            c=std::tolower(c);  
        if (tmp=="red") I = red; 
        else if (tmp=="blue") I = blue;   
        // but what happens if the string is invalid ???
    }
    return is ;
}
std::ostream& operator<<( std::ostream& os, Color& O ) 
{
    std::string tmp; 
    switch (O) {
        case red:  tmp="red"; break; 
        case blue: tmp="blue"; break; 
        default:   tmp="oops!!";
    }
    return os<<tmp ;
} 

Конечно, это только наивный пример. В действительности у вас, вероятно, будет std :: map для хранения связи между строкой и перечислением, и наоборот.

Стоит знать:

Перечислители в перечислении могут быть сопоставлены с целыми значениями. По умолчанию первый перечислитель (red) сопоставлен с 0. Следующие перечислители получают значение, которое на 1 больше, чем предыдущие (т. Е. blue будет равно 1).

Но вы можете установить значение (например, enum Color { red=2, green, blue=green+4 };). Вот почему допустимо делать между int и enum. Но будьте очень осторожны при этом, потому что, как только целое число не соответствует точно значению перечислителя, оно может стать сложным.

...