• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Enum - wczytywanie

VPS Starter Arubacloud
0 głosów
435 wizyt
pytanie zadane 20 czerwca 2018 w C i C++ przez Agnes Użytkownik (990 p.)
Wiem, że dla enuma nie ma zdefioniowanego operatora >>, więc jak mogę wczytać obiekt typu enum? Chyba użycie scanf() nie jest dobrym pomysłem?

2 odpowiedzi

0 głosów
odpowiedź 20 czerwca 2018 przez RafalS VIP (122,820 p.)

Wczytaj inta i zrób rzutowanie tego inta na enum.

#include <iostream>
using namespace std;

enum class MyEnum
{
	zero
};

int main() {
	int x;
	cin >> x;
	MyEnum m = static_cast<MyEnum>(x);
	//lub rzutowanie w stylu C czyli
	MyEnum m2 = (MyEnum)x;
	//ale static_cast jest bezpieczniejszy
}

 

komentarz 20 czerwca 2018 przez Agnes Użytkownik (990 p.)
Tylko, że muszę liczyć się z tym, że użytkownik dostanie, takie polecenie, które sprawi, że wpisze łańcuch znaków i on ma zostać przypisany do pola struktury, którego typem jest enum. Dlaczego nie mogę zainicjalizować x jako string i potem rzutować ze stringa na enum?
komentarz 20 czerwca 2018 przez RafalS VIP (122,820 p.)

Pod enumem zazwyczaj siedzi int, typ można wybrać, ale musi on być typem prostym, więc string odpada:

#include <iostream>
using namespace std;
 
enum MyEnum
{
    zero,
    jeden
};
 
int main() {
    cout<<jeden<<endl;
}

To wypisze 1, a nie nazwe jeden, która dostępna jest tylko w kodzie. Nie możesz bezpośrednio wypisać nazwy którą nadałaś identyfikatorowi w enumie, tak samo jak nie możesz wypisać nazwy zmiennej. Jeśli faktycznie potrzebujesz takiej funkcji to wykorzystaj mape:

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

enum class MyEnum
{
	zero,
	jeden
};

int main() {
	unordered_map<MyEnum, std::string> MyEnumNames;
	MyEnumNames[MyEnum::zero] = "zero";
	MyEnumNames[MyEnum::jeden] = "jeden";
}

 

0 głosów
odpowiedź 21 czerwca 2018 przez mokrowski Mędrzec (156,220 p.)

Po pierwsze to nie jest prawda że należy "sztywno rzutować na int". Typ enum class może mieć rodzica innego niż int. Często się tak robi szczególnie w embedded gdzie taki enum przechowuje np. maski lub wartości wpisywane na dany port. Oto prosty przykład:

#include <iostream>
#include <cstdint>

// AARRGGBB format..
enum class Color: uint32_t {
    Window = 0x00808080,
    Button = 0x80909090,
    Menu = 0x40fAFAFA,
    Font = 0x00000000
};

int main() {
    // Pobranie typu z którego dziedziczy enum class Color
    typename std::underlying_type<Color>::type x = 0x000000;
    Color color = static_cast<Color>(x);
    if(color == Color::Font) {
        std::cout << "Wprowadzono kolor znaku.\n";
    }
}

Co do translacji std::string -> enum class, rzeczywiście można to zrobić na wiele sposobów i mapa jest stosunkowo prosta.

Kontynuacja poprzedniego przykładu:

#include <iostream>
#include <iomanip>
#include <cstdint>
#include <unordered_map>

// AARRGGBB format..
enum class Color: uint32_t {
    Window = 0x00808080,
    Button = 0x80909090,
    Menu = 0x40fAFAFA,
    Font = 0x00000000
};

void show_color_names(const std::unordered_map<std::string, Color>& color_map) {
    std::cout << "Podaj nazwę z następującego zbioru [ ";
    for(const auto& pr: color_map) {
        std::cout << pr.first << ' ';
    }
    std::cout << " ]: ";
}

std::string read_color_name() {
    std::string color_name;
    std::cin >> color_name;
    return color_name;
}

Color read_color_by_name() {
    const static std::unordered_map<std::string, Color> str_to_color_map{
        {"Window", Color::Window},
        {"Button", Color::Button},
        {"Menu", Color::Menu},
        {"Font", Color::Font}
    };

    Color color_value;
    for(;;) {
        show_color_names(str_to_color_map);
        auto color_name = read_color_name();
        auto it = str_to_color_map.find(color_name);
        if(it != str_to_color_map.cend()) {
            color_value = (*it).second;
            break;
        }
        std::cerr << "Nieprawidłowa nazwa. Spróbuj jeszcze raz.\n";
    }
    return color_value;
}

int main() {
    Color color = read_color_by_name();
    std::cout << "Wprowadzono kolor elementu o wartości hex: 0x"
        << std::hex << std::setw(8) << std::setfill('0')
        << static_cast<typename std::underlying_type<Color>::type>(color)
        << '\n';
}

 

komentarz 21 czerwca 2018 przez Agnes Użytkownik (990 p.)

Czy istnieje prostszy sposób takiej translacji? Dopiero zaczynam programować obiektowo.

Lub co polecasz mi ogarnąć, żeby w pełni zrozumieć Twój kod? frown

komentarz 21 czerwca 2018 przez mokrowski Mędrzec (156,220 p.)
Oczywiście. Możesz to zrobić "stadem if'ów". Ale to wygląda "barbarzyńsko" i jest trudne w utrzymaniu (pilnowanie by każda sekcja if odpowiadała elementowi z enum class). Jeszcze gorsze jest switch case. Utrzymanie kodu ze switch case jest bardzo utrudnione...

http://en.cppreference.com/w/

https://www.amazon.com/Standard-Library-Tutorial-Reference-2nd/dp/0321623215

Podobne pytania

0 głosów
1 odpowiedź 325 wizyt
pytanie zadane 20 lipca 2023 w C i C++ przez Krzysztofs1234 Użytkownik (890 p.)
+1 głos
2 odpowiedzi 292 wizyt
pytanie zadane 25 grudnia 2020 w C i C++ przez TOWaD Mądrala (6,000 p.)
0 głosów
1 odpowiedź 520 wizyt
pytanie zadane 10 czerwca 2020 w C i C++ przez ResCrove Obywatel (1,700 p.)

92,775 zapytań

141,703 odpowiedzi

320,568 komentarzy

62,109 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...