[Gelöst] "Enum to string"



  • Hallo zusammen,

    mir ist grad eine Frage gekommen:

    Wenn ich so ein enum hab:

    enum Foo {
        bla1, bla2, bla3
    };
    

    Kann ich irgendwie die Namen aus einem int bekommen, sprich

    machIrgendwas(0);   // ergibt "bla1"
    machIrgendwas(1);   // ergibt "bla"
    // usw.
    

    Oder geht es tatsänlich nur mit so einer Funktion:

    string foo_to_str(int i)
    {
        switch (i) {
        case 0:
            return "bla1";
        // ...
        }
    }
    


  • Ein Array mit Strings wäre fein.



  • sprich

    enum Foo {
        bar1, bar2, bar3, count
    };
    
    array<string, count> foos { "bar1", "bar2", "bar3" };
    
    Foo f { bar3 };
    cout << foos[bar3];
    

    ?

    Scheint mir definitv eine nettere Lösung zu sein, wenns so gemeint war, danke.



  • Jupp, es war genau so gemeint.

    edit: aber std::string würde ich im allgemeinen nicht dafür bemühen, wo char* reicht (mit viel const).



  • Für "Hardcore" Lösungen auch hier nochmal: http://www.c-plusplus.net/forum/328440

    (Warum so kompliziert? Ich hatte es schon zu oft, dass ich die enum values geändert habe, ohne die Strings mit zu ändern, und das dann das ganze immernoch kompilierte, aber zu Laufzeitfehlern führte oder noch schlimmer: falschen Ausgaben. Bei den Lösungen ist man davor sicher und vermeidet Duplikationen)



  • Tim06TR schrieb:

    (Warum so kompliziert? Ich hatte es schon zu oft, dass ich die enum values geändert habe, ohne die Strings mit zu ändern, und das dann das ganze immernoch kompilierte, aber zu Laufzeitfehlern führte oder noch schlimmer: falschen Ausgaben. Bei den Lösungen ist man davor sicher und vermeidet Duplikationen)

    (Keine Zeile Anderscode zwischen den enum und das array oder irgendwie unittesten. Bin mir sicher, der Riesencode führt letztendlich zu mehr Arbeit.)



  • Das ist zwar offtopic, aber ich warte immernoch darauf, dass mir jemand zeigt, wie man in C++ VERNÜNFTIG unit tests schreibt. Ich habe einen Vortrag gesehen und als der dann (einfache) Templates in Vererbungshierarchien umgeschrieben hat um den Code testbar zu machen, habe ich aufgehört zuzuhören. Ein anderer Vortrag war über ein Eclipse Plugin und damit vollkommen unbrauchbar, außerdem viiieeel zu grundlegend.
    Automatisiertes testen gehört natürlich dazu. Bisher habe ich mir, wenn ich sowas gemacht habe, immer selbst ein komplett neues Programm geschrieben, dass für tests gebaut wird und ausgeführt.



  • ist doch einfach...

    enum Foo {
        bla, blub, blumm, count
    };
    array<string, count> foos { "bla", "blub", "blumm" };
    assert(count == foos.size())
    

    oder versteh ich da was falsch? Ich finde zumindest die Lösungen von z.B. Arcoth sehr unübersichtlich (für mich auch unverständlich)

    Also ich habe kapiert, dass

    array<char*, size>
    

    völlig ausreicht, aber was ist mit const gemeint? Etwa

    const array<char*, size>
    

    ?

    Tut mir leid, dass ich so blöd nachfrage, aber ich bekomme folgende Warnung (bei meinen Einstellungen auch ein Fehler):

    error: deprecated conversion from string constant to 'char*' 
    [-Werror=write-strings]
    

    Für diese Zeile

    const array<char*, count> foos { "bar1", "bar2", "bar3" };
    

    Soll ich das einfach umstellen und die Warnung ignorieren?

    P.S.: Das off-topic ist nicht schlimm, würde mich eventuell auch interessieren^^
    Mach doch einfach einen Thread dazu auf, dann wird das mal für alle geklärt.



  • Tim06TR schrieb:

    Das ist zwar offtopic, aber ich warte immernoch darauf, dass mir jemand zeigt, wie man in C++ VERNÜNFTIG unit tests schreibt. Ich habe einen Vortrag gesehen und als der dann (einfache) Templates in Vererbungshierarchien umgeschrieben hat um den Code testbar zu machen, habe ich aufgehört zuzuhören. Ein anderer Vortrag war über ein Eclipse Plugin und damit vollkommen unbrauchbar, außerdem viiieeel zu grundlegend.
    Automatisiertes testen gehört natürlich dazu. Bisher habe ich mir, wenn ich sowas gemacht habe, immer selbst ein komplett neues Programm geschrieben, dass für tests gebaut wird und ausgeführt.

    Ich baue eine Testfunktion, die die Klasse rundum testet. Per Compilerschalter sind alle solche Funktionen dann noch autostartbar und gut ist's. Ob das vernünftig genug ist oder zu wenig javaesk?



  • [quote="HarteWare"]const[(quote]
    Ja, viele const. Soo viele, daß ich sie nicht einzeln nennen wollte.

    enum foo{eins,zwei,size};
    array<char*,foo::size> foos={"eins","zwei"};
    …
    int main(){
    	foos[eins][0]='o';//heißt ab jetzt "oins","zwei". 
    }
    

    Ok, da darf man eh nicht rumschreiben in Stringliterale rein. Gibt Schutzverletzung. Und Dein Compiler warnt ja schon davor. Also

    enum foo{eins,zwei,size};
    array<char const*,foo::size> foos={"eins","zwei"};
    
    int main(){
    	//foos[eins][0]='o';geht nicht mehr
    }
    

    Nächster Unfug:

    int main(){
    	//foos[eins][0]='o';geht nicht mehr
    	foos[eins]="oins";
    }
    

    Mit Verhinderungscode

    array<char const*,foo::size> const foos={"eins","zwei"};
    

    Das dritte const

    array<char const* const,foo::size> const foos={"eins","zwei"};
    

    braucht man nicht, weil der op[]const vom array const zurückgibt.



  • Ich persönlich mag die Lösung mit dem Switch lieber. Da kann man nämlich sofort sehen welcher String zu welchem Wert gehört und sicherer ist die Lösung auch. Die Lösung mit dem Array wird für große enums schnell unübersichtliche insbesondere wenn man das enum später noch erweitern möchte. Da kommt es schnell zu Vertauschungen oder ungültigen Speicherzugriffen. Schneller dürfte es bei einem guten Kompiler auch nicht sein.



  • In C# kommt jetzt das Keyword 'nameof' hinzu: new features in C# 6

    Vllt. wäre dies auch etwas für den ISO C++ Standard? Denn der Compiler weiß ja immer noch am besten wie die Variablen und Konstanten etc. heißen 😉



  • Ich denke so weit müsste man gar nicht gehen. Was ich aber nicht verstehe ist, warum man dem enum nicht gleich einen Ausgabeoperator spendiert hat. Enums erfüllen doch genau den Zweck einen Wert als Textrepresentation darstellen zu können warum soll das dann bei der Ausgabe nicht einfach auch gehen?



  • volkard schrieb:

    Ja, viele const. Soo viele, daß ich sie nicht einzeln nennen wollte.

    Ich danke für die super ausgeführte und verständliche Erklärung 👍



  • TNA schrieb:

    Ich denke so weit müsste man gar nicht gehen. Was ich aber nicht verstehe ist, warum man dem enum nicht gleich einen Ausgabeoperator spendiert hat. Enums erfüllen doch genau den Zweck einen Wert als Textrepresentation darstellen zu können warum soll das dann bei der Ausgabe nicht einfach auch gehen?

    Man kann, wenn man will, den Ausgabeoperator für enums definieren. Da kann man es dann auch genau so machen, wie man es haben will.
    Ich will hier jetzt keine alten Threads wieder aufgraben, sondern das ist nur der Vollständigkeit halber.

    P.S.: Hätt ich auch einfach meinen vorherigen Beitrag editieren können *facepalm*



  • TNA schrieb:

    Ich denke so weit müsste man gar nicht gehen. Was ich aber nicht verstehe ist, warum man dem enum nicht gleich einen Ausgabeoperator spendiert hat. Enums erfüllen doch genau den Zweck einen Wert als Textrepresentation darstellen zu können warum soll das dann bei der Ausgabe nicht einfach auch gehen?

    Weil C++ Programme unter Umständen auf Systemen laufen, wo es keine Möglichkeit gibt irgendetwas nativ auszugeben. Und andere können die iostream Library vielleicht aus Performancegründen nicht verwenden.
    Ich find das auch gut so, je weniger Kopplung zwischen Sprache und Bibliothek, desto besser. Ich find schon allein so Sachen wie set_terminate_handler, der aufgerufen wird, wenn ein Sprachefeature (!) schief geht, ist schon grenzwertig.


Log in to reply