Как вывести enum
Перейти к содержимому

Как вывести enum

  • автор:

Как вывести enum

Перечисления (enum) представляют еще один способ определения своих типов. Их отличительной особенностью является то, что они содержат набор числовых констант. Перечисление имеет следующую форму:

enum class имя_перечисления < константа_1, константа_2, . константа_N>;

После ключевых enum class идет название перечисления, и затем в фигруных скобках перечисляются через запятую константы перечисления.

Определим простейшее перечисление:

enum class Day

В данном случае перечисление называется Day и представляет дни недели. В фигурных скобках заключены все дни недели. Фактически они представляют числовые константы.

Каждой константе сопоставляется некоторое числовое значение. По умолчанию первая константа получает в качестве значения 0, а остальные увеличиваются на единицу. Так, в примере выше Monday будет иметь значение 0, Tuesday — 1 и так далее. Таким образом, последняя константа — Sunday будет равна 6.

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

Day today ; // или так //Day today = Day::Thursday;

В данном случае определяется переменная today , которая равна Day::Thursday , то есть четвертой константе перечисления Day.

Чтобы вывести значение переменной на консоль, можно использовать преобразование к типу целочисленному типу:

#include enum class Day ; int main() < Day today ; std::cout (today)

То есть в данном случае на консоль будет выведено Today: 3 , так как константа Thursday имеет значение 3.

Мы также можем управлять установкой значений в перечислении. Так, мы можем задать начальное значение для одной контанты, тогда у последуюших констант значение увеличивается на единицу:

enum class Day ;

В данном случае Tuesday будет равно 2, а Sunday — 7.

Можно назначить каждой константе индивидуальное значение или сочетать этот подход с автоустановкой:

enum class Day ;

В данном случае Saturday будет равно 7, а Sunday — 1.

Можно даже назначать двум константам одно и то же значение:

enum class Day ;

Здесь константы Monday и Mon имеют одно и то же значение.

Можно присвоить константам значение уже имеющихся констант:

enum class Day ;

Стоит учитывать, что константы перечисления должны представлять целочисленные константы. Однако мы можем выбрать другой целочисленный тип, например, char :

enum class Operation: char ;

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

#include enum class Operation: char ; int main() < std::cout (Operation::Add) (Operation::Subtract) (Operation::Multiply)

Применение перечислений

Перечисления удобны, когда необходимо хранить ограниченный набор состояний и в зависимости от текущего состояния выполнять некоторые действия. Например:

#include enum class Operation ; void calculate(int n1, int n2, Operation op) < switch (op) < case Operation::Add: std::cout > int main() < calculate(10, 6, Operation::Add); // 16 calculate(10, 6, Operation::Subtract); // 4 calculate(10, 6, Operation::Multiply); // 60 >

В данном случае все арифметические операции хранятся в перечислении Operation. В функции calculate зависимости от значения третьего параметра — применяемой операции выполняются определенные действия с двумя первыми параметрами.

Подключение констант перечисления

При обращении к контантам перечисления по умолчанию необходимо указывать название перечисления, например, Day::Monday . Но начиная со стандарта C++20 мы можем подключить константы перечисления в текущий контекст с помощью оператора using .

using enum Day;

И в дальнейшем использовать только имя констант:

#include enum class Day ; using enum Day; // подключаем константы перечисления в текущую область видимости int main() < Day today ; // используем только имя константы // или так //Day today = Thursday; std::cout (today) << std::endl; // 3 // выводим значение констаты Sunday std::cout (Sunday) 

Также мы можем подключить только одну константу:

using Day::Monday; // подключаем только Monday . Day today ;

В данном случае подключаем только константу Day::Monday . Для обращения к дргуим константам по прежднему необходимо использовать имя перечисления.

Поскольку такая возможность добавлена лишь начиная со стандарта С++20, то при компиляции с g++ или clang++ добавляется соответствующий флаг - -std=c++20

Перечисления в С-стиле

Стоит отметить, что раньше в С++ использовалась другая форма перечислений, которые пришли из языка С и определяются без ключевого слова class :

#include enum Day ; int main() < Day today = Tuesday; std::cout 

Такие перечисления еще называют unscoped (то есть не ограниченные ни какой областью видимостью). Естественно такие перечисления можно встретить в старых программах. Однако в виду того, что они потенциально могут привести к большему количеству ошибок, то в настоящее время такая форма все меньше и меньше используется.

Вывести содержимое Enum

Подскажите как вывести содержимое enum. Тоесть у меня есть Student_FirstName< Denys, Rabbit, Milana, Olexandr>;
Выводятся на консоль только числа, а мне нужно имена. Неужели без switch-case никак?

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Работа с enum, как вывести значение
не могу разобраться с enum . По одному вывести могу,но надо,чтобы пользователь смог сделать выбор .

Обобщения, где в качестве параметра enum (класс наследник Enum)
Хочу создать такой класс: public class Example <Y extends Enum> < . >А потом: enum Ex

Enum или enum class и где его располагать
Для удобства хочу сделать перечисление уровней через enum. Но запутался, как правильно. Просьба.

Вывести текст перечисления Enum
Такой вопрос. Есть такое enum chislo < Один, Два, Три>Как теперь вызвать слово "Два"? то есть я.

316 / 178 / 73
Регистрация: 18.01.2014
Сообщений: 387

1 2 3 4 5 6 7 8
#include #include int main() { enum Student_FirstName{ Denys, Rabbit, Milana, Olexandr }; std::string Student_FirstNameString[]{"Denys", "Rabbit", "Milana", "Olexandr" }; std::cout  Student_FirstNameString[Milana]  std::endl; }

Регистрация: 29.06.2014
Сообщений: 179

Возможно проблема в том, что я использую это внутри метода перегрузки потока >>?

____Забыл подключить стринг.

2771 / 1924 / 570
Регистрация: 05.06.2014
Сообщений: 5,582

Почему то пишет Error 1 error C2679: binary '

static const char*names[]={"Denys", "Rabbit", "Milana", "Olexandr"}; std::coutnames[Milana]std::endl;

Форумчанин

Эксперт CЭксперт С++

8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
На уровне плясок

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
#include #include #include #define NAMES_ENUM(DO) \ DO(Denys) \ DO(Rabbit) \ DO(Milana) \ DO(Olexandr) #define MAKE_ENUM(VAR) VAR, #define MAKE_STRINGS(VAR) #VAR, enum Names { NAMES_ENUM(MAKE_ENUM) }; const std::vectorstd::string> NamesValues { NAMES_ENUM(MAKE_STRINGS) }; int main() { std::cout  [Denys]; }

Эксперт CАвтор FAQ

21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30

Напрямую никак. Когда работаешь с переменной под именем "x", ты ведь можешь напечатать её значение, но не можешь напечатать имя (без дополнительных телодвижений). Элементы enum'а - это тоже имена, но имена констант, а не переменных

Почетный модератор

Эксперт С++

5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907

ЦитатаСообщение от Evg Посмотреть сообщение

без дополнительных телодвижений
Вот это-то и самое интересное.
693 / 303 / 99
Регистрация: 04.07.2014
Сообщений: 845

Лучший ответ

Сообщение было отмечено SatanaXIII как решение

Решение

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#include #include #define ENUM_STUDENT_FIRST_NAME \ X(STUDENT_FIRST_NAME_DENYS, "Denys") \ X(STUDENT_FIRST_NAME_RABBIT, "Rabbit") \ X(STUDENT_FIRST_NAME_MILANA, "Milana") \ X(STUDENT_FIRST_NAME_OLEXANDR, "Olexandr") enum StudentFirstName{ # define X(Enum, String) Enum, ENUM_STUDENT_FIRST_NAME # undef X }; const std::string student_first_name_strings[] = { # define X(Enum, String) String, ENUM_STUDENT_FIRST_NAME # undef X }; std::string to_string(StudentFirstName e) { return student_first_name_strings[(int)e]; }; int main() { std::cout  to_string(STUDENT_FIRST_NAME_DENYS)  std::endl; };

Добавлено через 24 минуты
Для C++11 можно подправить до:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#include #include #define ENUM_STUDENT_FIRST_NAME \ X(Denys) \ X(Rabbit) \ X(Milana) \ X(Olexandr) enum class StudentFirstName{ # define X(Enum) Enum, ENUM_STUDENT_FIRST_NAME # undef X }; const std::string student_first_name_strings[] = { # define X(String) #String, ENUM_STUDENT_FIRST_NAME # undef X }; std::string to_string(StudentFirstName e) { return student_first_name_strings[(int)e]; }; int main() { std::cout  to_string(StudentFirstName::Denys)  std::endl; };

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Enum? как к объектам enum дать значения?
Здравствуйте для элементом enum только с помощью конструкторов и set могу дать значения? и еще enum.

Прочитать содержимое dbf (файл SER.Dbf). И вывести содержимое нескольких полей
Всем привет) Можете пожалуйста помочь, может кто хорошо разбирается в работе с dbf файлами.

Вывести название цифр от 0 до 9, используя enum
Написала такую программу которая выводит на экран названия цифра. То есть как то так: С клавиатуры.

Как вывести атрибуты enum списка в DropDownList
Привет! Подскажите пожалуйста как вывести атрибуты enum списка в DropDownList? Есть список: .

Вывести элемент enum

В С++ такое поведение не предусмотрено. Вы с таким же успехом могли бы спросить: "как напечатать имя переменной, адрес которой хранит указатель".

20 мар 2013 в 14:09

а никак, кроме как написать свою функцию для преобразования/вывода. Некоторые изголяются, делая свои макросы для этого.

20 мар 2013 в 14:12
Можно сделать через map
20 мар 2013 в 14:53
ОК, я понял что простым способом этого не сделать, только через танцы с бубном :/
20 мар 2013 в 15:11
Так это ж С++, а не питон )))
20 мар 2013 в 15:16

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Доброго времени суток! Ответ на Ваш вопрос зависит от того что вы хотите получить. Если вы хотите получить имя элемента перечисления, то Вам необходимо перегрузить операторы ввода/вывода в поток. Этот прием я узнал из книги Б. Страуструпа "Дизайн и эволюция С++" (очень советую почитать - можно много почерпнуть полезного). Если же вы хотите просто узнать сам элемент перечисления, то тогда используйте static_cast для безопасного приведения типов.

#include #include #include enum Type < A = 0, B, C >; std::ostream& operator return (out); > std::istream& operator >> (std::istream& input, Type& t) < std::string s; input >> s; if (s == "A") < // неявная конвертация в Type t = A; >else if (s == "B") < t = B; >else if (s == "C") < t = C; >else < // здесь можно выкинуть исключение throw std::runtime_error("incorrect input"); >return (input); > int main(int argc, char *argv[]) < using namespace std; Type type; try < cin >> type; > catch(std::exception& e) < cout cout 
)" data-controller="se-share-sheet" data-se-share-sheet-title="Поделиться ссылкой на ответ" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="answer" data-se-share-sheet-social="facebook twitter " data-se-share-sheet-location="2" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f3.0%2f" data-se-share-sheet-license-name="CC BY-SA 3.0" data-s-popover-placement="bottom-start">Поделиться
)" title="">Улучшить ответ
ответ дан 23 мар 2013 в 15:30
Добавить комментарий|
1

Ну например можно было погуглить по запросу "c++ enum to string" и добрый Гугл выдал бы вам первым же результатом вот это Немного нехитрых колдунств с вашей стороны, и все работает

)" data-controller="se-share-sheet" data-se-share-sheet-title="Поделиться ссылкой на ответ" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="answer" data-se-share-sheet-social="facebook twitter " data-se-share-sheet-location="2" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f3.0%2f" data-se-share-sheet-license-name="CC BY-SA 3.0" data-s-popover-placement="bottom-start">Поделиться
)" title="">Улучшить ответ
)">изменён 23 мая 2017 в 12:39
Дух сообществаБот
1
ответ дан 20 мар 2013 в 14:08
3
    Офигенный ответ. Отсылка к SO, где еще неочевидно, что правильно отвечают.
    – avp
    20 мар 2013 в 14:18
    Ну почему, норм ответ. там всё такми много вариантов + заметил там ссылку на похожую тему, где тоже большое обсуждение. я просто писал в гугле различные варианты на русском, поэтому и не попал туда.
    – Comfmore
    20 мар 2013 в 15:15
    @Comfmore, в SO только один ответ (с мапом) правильный. В остальных неявно предполагается, что enum переменные, используемые как индексы имеют значения 0, 1, . А это язык не гарантирует.
    – avp
    20 мар 2013 в 16:23
Добавить комментарий|
1

Посмотрите для char *, аналогично для int

enum ex ; struct enex < ex en; const char *name; >; static ex get_enum (const char *name) < static struct enex en[] = ,,,>; for (int i = 0; en[i].name; i++) if (strcmp(name,en[i].name) == 0) return en[i].en; return NONE; >

Перечисления enum

Помимо ранее рассмотренных примитивных типов данных, в C# существует отдельный тип enum или перечисление, который состоит из списка именованных констант.

Перечисление может содержать константы одного и того же типа данных, который указывается при объявлении перечисления.

Синтаксис объявления перечисления следующий:

[modifier enum] EnumName [: type]

Первым идет необязательный модификатор, дальше после ключевого слова enum необходимо указать имя перечисления, после имени может идти необязательный тип данных, если тип не указан, то константы будут иметь тип данных – int(тип по умолчанию). В фигурных скобках, через запятую, указываются имена констант, которым можно назначить значения, при этом сразу несколько констант могут иметь одно и то же значение. Если значения констант не заданы, то они получают значения по умолчанию.

Логика присваивания значения по умолчанию:

  • Если для первой константы не указано значение, то тогда ей присваивается 0;
  • Если константе не задано значение, то ей присваивается значение на единицу больше предыдущего, даже если в последующих константах это значение используется.

Перечисления могут иметь один из целочисленных типов данных:

Рассмотрим перечисления на реальном примере, напишем enum для хранения названий цифр двоичной системы:

enum BinaryDigit < Zero, //0 One //1 > 

В данном случае enum имеет тип данных по умолчанию(int), и поскольку значения для констант не заданы, всем присваиваются значения начиная с нуля, в итоге получаем соответствие цифр их названиям.

Рассмотрим ещё один пример:

enum Status : byte < Error = 10, InProgress, //11 Done = 77 > 

В этом перечислении задан тип данных byte, при этом константе InProgress будет присвоено значение 11, так как оно вычисляется по предыдущему.

Обратите внимание, если в списке констант перечисления имеется константа без значения, то ей присваивается значение на единицу больше предыдущего, даже если список содержит константы с такими значениями.

enum Color < Blue = 1, Black, //В данном случае Black == White == 2. White = 2 > 

Перечисления можно объявлять как внутри класса, так и в неймспейсе(namespace). При этом каждое перечисление является новым типом данных, для которого можно создавать переменные, при этом переменная может принимать значения только из списка констант перечисления:

using System; namespace ConsoleApp < enum BinDigit : uint < Zero, One >class Program < enum LedBulbColor : int < WarmWhite = 3500, White = 4200, CoolWhite = 6100 > static void Main(string[] args) < BinDigit d; d = BinDigit.One; d = BinDigit.Zero; var ledBulb = LedBulbColor.CoolWhite; Console.WriteLine(d); //Zero Console.WriteLine(ledBulb); //CoolWhite Console.ReadLine(); > > > 

Хотя константа перечисления связана с числовым значением, на экран выводятся текстовые названия констант. Для того чтобы получить целочисленное значение константы, нужно преобразовать её тип:

var x = (uint) BinDigit.One; //1 

Где используются перечисления

Обычно enum используется для того, чтобы ограничить диапазон входных значений, это в свою очередь избавляет от дополнительных проверок, и помогает избежать ошибок времени выполнения программы.

К примеру светофор может иметь три состояния которые удобно описать с использованием перечисления:

using System; namespace ConsoleApp < class Program < enum TrafficLight < Red, Yellow, Green >static void Main(string[] args) < var t = TrafficLight.Green; Console.WriteLine(t); Console.ReadLine(); > > > 

Также перечисления удобно использовать в операторе switch. Рассмотрим в качестве примера программу для вывода названий цветов модели CMY:

using System; class Program < enum CMYColor < Cyan, Magenta, Yellow >enum Language < English, Russian >private static string CMYToText(CMYColor c, Language lang) < var s = string.Empty; if (lang == Language.English) < s = c.ToString(); >else < switch (c) < case CMYColor.Cyan: s = "Голубой"; break; case CMYColor.Magenta: s = "Пурпурный"; break; case CMYColor.Yellow: s = "Желтый"; break; > > return s; > static void Main(string[] args) < for (int i = 0; i < 3; i++) < //конвертируем int в enum var myColor = (CMYColor)i; Console.WriteLine(CMYToText(myColor, Language.Russian)); > Console.ReadLine(); > > 

Программа поддерживает вывод названий цветов на двух языках: английском и русском.

Перечисления активно используются в разных типах программ, для ограничения количества вариантов и улучшения читабельности кода. К примеру в консольных и Windows Forms приложениях доступны перечисления которые описывают цвета(ConsoleColor и Color) и клавиши клавиатуры(ConsoleKey и Keys).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *