char * mit enum wert vergleichen



  • std::map

    greetz, Swordfish



  • oder das. 🙂



  • traceman schrieb:

    ...Diesen String möchte ich dann vergleichen mit einem Belegung ...

    Dann tu das doch auch .... 😕
    Wo steht denn da was von "char*" ?

    Gruß,

    Simon2.



  • Danke! Aber gibts da keine bessere methode? Die ganzen Werte z.B. 9600 und viele andere stehen in einer global.h. Wäre uncool wenn ich die ganzen werte in eine switch anweisung reinschreiben müsste?! Ich muss doch irgendwie an die 2 kommen?!



  • (Pseudocode)

    if (configFileString=="Baudrate =") thread_prirec.baudRate = BAUD9600;
    

    so klappts zwar aber die Abfrage muss einzeln erfolgen



  • --- hier stand nix wichtiges ---



  • du fragst ja gar nirgends ab, was hinter "Baudrate =" steht.
    Soll heißen, thread_prirec.baudRate wird immer auf BAUD9600 gesetzt werden...

    mit std::map ginge es wohl so:

    #include <map>
    
    //...
    std::map<string, BaudRateType> translator;
    translator["Baudrate = 9600"] = BAUD9600;
    translator["Baudrate = 4800"] = BAUD4800;
    ...
    
    thread_prirec.baudRate = translator[configFileString];
    


  • hmm also irgendwie bin ich heut nicht mehr auf der höhe...

    muss es wohl oder übel über eine abfrage machen...



  • Diese Art der map-Abfrage geht schief, wenn der übergebene String keinen vorhandenen Schlüssel darstellt.
    Da ist mir ein switch mit default-Behandlung lieber. 🙂



  • queer_boy schrieb:

    du fragst ja gar nirgends ab, was hinter "Baudrate =" steht.
    Soll heißen, thread_prirec.baudRate wird immer auf BAUD9600 gesetzt werden...

    mit std::map ginge es wohl so:

    #include <map>
    
    //...
    std::map<string, BaudRateType> translator;
    translator["Baudrate = 9600"] = BAUD9600;
    translator["Baudrate = 4800"] = BAUD4800;
    ...
    
    thread_prirec.baudRate = translator[configFileString];
    

    Ok..aber ich hab schon eine längere Liste.... Kann der nicht schauen ob String 9600 == BaudRateType.BAUD9600 ist? Eine Abfrage wäre schon aufwendig... Wie kann ich denn allgemein auf Werte eines Enumerators zugreifen? Nur über die Namen oder auch über einen Index?



  • traceman schrieb:

    Ok..aber ich hab schon eine längere Liste.... Kann der nicht schauen ob String 9600 == BaudRateType.BAUD9600 ist? Eine Abfrage wäre schon aufwendig... Wie kann ich denn allgemein auf Werte eines Enumerators zugreifen? Nur über die Namen oder auch über einen Index?

    Du musst erstmal verstehen was ein enum unter C++ ist.

    a) Textvergleich ist unmöglich, da ein Enum-Wert nur ein symbolischer Wert ist (Zur Laufzeit ist es ein Zahlenwert).
    b) Ein Indexzugriff auf ein Enum ist ebenso nicht möglich, da es im wesentlichen nur eine unsortierte Sammlung von Konstanten darstellt die einmalig durch den Compiler aufgelöst wird.

    Die Lösung über die Map mag dir nicht gefallen, sie stellt aber mit den sinnvollsten Ansatz dar.

    cu André



  • traceman schrieb:

    ... soll eine Abfrage kommen die schaut welchen Wert 9600 im Enumerator mit dem Namen BaudRateType hat. (Hier =2 da BAUD2400 =0, BAUD4800 =1, BAUD9600=2). Die 2 ist ein ganzzahliger Wert.
    Weiss jemand einen Tipp?

    int main()
    {
        // Du musst die Baudrate aus dem String in einen int umwandeln.
    	// diesen  int-Wert vergleichst Du dann in einer Schleife mit den
    	// Werten im BaudRateType-Array. Die gesuchte "ganze Zahl" entspricht 
    	// dann dem Index aus der for-Schleife! 
    	const int BaudRaten = 9; 
    	int BaudRateType[BaudRaten] = {
        2400,
        4800,
        9600,
        14400,            
        19200,
        38400,
        56000,    
        57600,
        115200
        };
    	int BaudRateAusString = 9600;
    
    	int index;
    
    	for (index = 0; index < BaudRaten; index++)
    	{
    		if (BaudRateType[index] == BaudRateAusString)
    			break;
    	}
    	// index hat ab hier den Wert 2
    
       return 0;
    }
    


  • Aha, vielen Dank (auch für die letzte Lösung)... ich seh schon: Ich komm wohl mit dem Enum so nicht weiter. Dann werde ich wohl oder übel auf eine map zurückgreifen. Im Prinzip kann ich mich ja auch die relevanten Parameter einschränken dann wird die Liste nicht so lang.
    Danke und Gruss



  • Hi,

    was musst Du denn in Abhängigkeit vom Input machen ? Bisweilen bietet sich für sowas auch ein Funktionspointer an, indem man bei der Initialisierung der map gleich den string mit der auszuführenden Funktion verknüpft.
    Damit spart man sich den switch und hat diese Verknüpfung nur an einer relevanten Stelle und nicht an 2 (map-Init & switch). Besonders praktisch, wenn neue Funktionen dazukommen.
    Wenn allerdings die Funktionalität zu marginal ist, um sie in eine separate Funktion zu packen, lohnt sich das nicht.

    Gruß,

    Simon2.



  • Keine Alternative? Müsste man aus dem eingelesenen String nur noch die Zahl extrahieren.

    enum BaudRateType {
        BAUD2400    =   2400,
        BAUD4800    =   4800,
        BAUD9600    =   9600,
        BAUD14400   =  14400,             
        BAUD19200   =  19200,
        BAUD38400   =  38400,
        BAUD56000   =  56000,    
        BAUD57600   =  57600,
        BAUD115200  = 115200,
    
    };
    


  • Fellhuhn schrieb:

    Keine Alternative? Müsste man aus dem eingelesenen String nur noch die Zahl extrahieren.

    enum BaudRateType {
        BAUD2400    =   2400,
        BAUD4800    =   4800,
        BAUD9600    =   9600,
        BAUD14400   =  14400,             
        BAUD19200   =  19200,
        BAUD38400   =  38400,
        BAUD56000   =  56000,    
        BAUD57600   =  57600,
        BAUD115200  = 115200,
    
    };
    

    Ich habe ja eine Funktion z.B. InitSerialBus(xxxx) und das xxxx (vom Typ BaudRateType) soll dynamisch ersetzt werden mit dem inhalt eines strings (dieser string kommt aus einem txt config file). Also bringen mir die festgelegten werte leider auch nichts 😕



  • traceman schrieb:

    ...
    Ich habe ja eine Funktion z.B. InitSerialBus(xxxx) und das xxxx (vom Typ BaudRateType) soll dynamisch ersetzt werden mit dem inhalt eines strings (dieser string kommt aus einem txt config file). Also bringen mir die festgelegten werte leider auch nichts 😕

    😮 🙄

    Also ehrlich gesagt, klingt das danach, als ob Du das alles viel zu kompliziert machst und mit einer normalen "string2Int"-Konvertierung fertig wärst.
    Kannst mal unter "Einmal String nach Zahl und zurück" hier im Forum nachsehen.
    Oder nimmst direkt:

    istringstream ist(configFileString);
       ist >> thread_prirec.baudRate;
       InitSerialBus(thread_prirec.baudRate);
    

    "configFileString" ist hier natürlich nur ein Beispiel; in Deinem Code wirst Du vermutlich jede ConfigFile-Zeile zerlegen in einen ParameterTyp- und einen -Wert-String ... und "ist" muss dann mit dem Wert-String initialisiert werden.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    InitSerialBus(thread_prirec.baudRate);
    

    Das Problem ist dass genau an der Stelle thread_prirec.baudRate ein Enumeratortyp stehen musss (in dem Fall also z.B. BAUD9600) und kein int oder string



  • traceman schrieb:

    Simon2 schrieb:

    InitSerialBus(thread_prirec.baudRate);
    

    Das Problem ist dass genau an der Stelle thread_prirec.baudRate ein Enumeratortyp stehen musss (in dem Fall also z.B. BAUD9600) und kein int oder string

    Also ist das eine vorgegebene Funktion, die damit auch ParameterBereich und vermutlich sogar den Typen (enum) vorgibt.
    Ergo: Es ist doch festgelegt und Du fährst mit der map gut.

    BTW: "map" ist hier sogar ziemlich wörtlich zu verstehen: Du "mappst" (im Sinne einer Abbildung) nämlich Deinen Parametertyp (string, Werte von Dir festgelegt) auf den der genutzten Schnittstelle (enums).

    Gruß,

    Simon2.



  • traceman schrieb:

    Simon2 schrieb:

    InitSerialBus(thread_prirec.baudRate);
    

    Das Problem ist dass genau an der Stelle thread_prirec.baudRate ein Enumeratortyp stehen musss (in dem Fall also z.B. BAUD9600) und kein int oder string

    Nicht desto Trotz ist ein enum ein Integerwert, und wenn du im Enum die Werte richtig verschlüsselt hast (Sprich z.b. BAUD9600 = 9600), läßt sich - vorausgesetzt es hat immer den gleichen Aufbau "BAUD<Zahl>" später über diesen Wert ein String generieren. Der Enum selbst ist freilich aber kein String.

    cu André


Anmelden zum Antworten