string zu byte



  • Das Auslesen soll doch als 'hex' geschehen, also:

    BYTE toByte(std::string const & str)
    {
        std::stringstream ss;
        ss << str;
        BYTE b;
        ss >> hex >> b;
        return b;
    }
    

    Evtl noch "0x" vorher in den Stream schreiben, also "ss << "0x" << str"...

    Ich persönlich nutze aber eigentlich immer diese Variante:

    std::istringstream ss(str);
    BYTE b;
    ss >> hex >> b;
    return b;
    

    bzw allgemein als Template:

    template<typename T>
    T fromStr(const string &str)
    {
        std::istringstream is(str);
        T t = T();
        is >> t;
        return t;
    }
    

    Und die Variante mit 'hex' kann sich nun jeder selbst basteln...



  • Wie gesagt, leider kann ich das Problem so nicht lösen, da die bytes nicht als bytes interpretiert werden, sondern als string.

    Beispiel:

    std::string str = "FF";
        ss << str; 
        BYTE b; 
        ss >> std::hex >> b; 
    // b is not 0xFF but 0x46 'F'
    


  • Old school:

    unsigned char c = 16 * ( str[1] - ('F' - 15)) + (str[0] - ('F' - 15));
    

    Sofern Großschreibung garantiert. Sonst noch sowas wie toupper().



  • Caligulaminus schrieb:

    Old school:

    unsigned char c = 16 * ( str[1] - ('F' - 15)) + (str[0] - ('F' - 15));
    

    Sofern Großschreibung garantiert. Sonst noch sowas wie toupper().

    Klappt nicht mit den Ziffern 0-9.



  • Hallo Epsylon,

    stimmt, 'BYTE' ist ja '[unsigned] char'.

    Lese es einfach als 'int' aus dem Stream und konvertiere es anschließend nach BYTE.



  • @Michael E.: Upps... danke.

    Lesen mit einem Auge und halbem Hirn führt eben doch zu Schwachsinn.

    unsigned char c = 16 * str[1] > '9' ? (str[1] - ('F' - 15)) : (str[1] - '0') + str[0] > '9' ? (str[0] - ('F' - 15)) : (str[0] - '0');
    

    Jetzt wirds aber auch wirklich unübersichtlich. 😃



  • #include <cctype>
    #include <stdexcept>
    
    inline int hexvalue(char c) {
      if(!std::isxdigit(c)) {
        throw std::invalid_argument("Keine hexadezimale Ziffer");
      }
    
      return std::isdigit(c) ? c - '0' : std::tolower(c) - 'a' + 10;
    }
    
    unsigned char c = hexvalue(str[0]) * 16 + hexvalue(str[1]);
    

    ?



  • Caligulaminus schrieb:

    @Michael E.: Upps... danke.

    Lesen mit einem Auge und halbem Hirn führt eben doch zu Schwachsinn.

    unsigned char c = 16 * str[1] > '9' ? (str[1] - ('F' - 15)) : (str[1] - '0') + str[0] > '9' ? (str[0] - ('F' - 15)) : (str[0] - '0');
    

    Jetzt wirds aber auch wirklich unübersichtlich. 😃

    Wenn schon ASCII-abhängig, dann richtig 😉

    cout << 16 * ((str[0] & 15) + 9 * !!(str[0] & 64)) + (str[1] & 15) + 9 * !!(str[1] & 64);
    


  • Michael E. schrieb:

    cout << 16 * ((str[0] & 15) + 9 * !!(str[0] & 64)) + (str[1] & 15) + 9 * !!(str[1] & 64);
    

    Und dazu noch case insensitive (gibt's dafür 'nen schönen deutschen Ausdruck?).

    Viel besser! 👍 🙂



  • Vielen Dank Michael E.! Die Lösung funktioniert super!
    Hoffentlich ist das bugfrei, denn ich hab keine Ahnung was da abgeht 🤡

    Danke auch an Caligulaminus und seldon

    Epsylon



  • Meine Lösung war eigentlich nur als Witz gedacht, denn sie verlässt sich auf den ASCII-Zeichensatz und ist ziemlich unintuitiv 😉 Aber na gut, wenns um Geschwindigkeit geht und man die Zeile gut kommentiert, kann man das akzeptieren.



  • Und außerdem dürfte sie auch alle ungültigen Zeichen berarbeiten (was sicher nicht im Sinne des Erfinders ist). Wenn du etwas verwertbares haben willst, sind die Antworten von Th69 und seldon vermutlich brauchbarer.



  • hi,

    Die Lösung funktioniert super, ich habe 3 Tage schon versucht es zu lösen.
    Die Daten sind ja immer im ASCII Zeichensatz, weil ich sie aus der Datei lese.
    Und ich kann garantieren, dass keine ungültigen Zeichen dabei sind.



  • Na wenn du unbedingt Programme schreiben willst, die du selber in einem Monat nicht mehr lesen kannst, wünsche ich dir viel Glück 😃 Du solltest trotzdem mal versuchen herauszufinden, WARUM diese Formel das macht was sie soll - und was herauskommt, wenn du ihr z.B. die Eingabe 'GG' vorsetzt.



  • Ich fürchte, ein Array mit 256 Bytes oder ein switch wären schneller und leichter zu lesen.



  • naja bei Seldons lösung muss ich extra eine neue Funktion deklarieren etc. da ist der Einzeiler doch nicht schlecht. Und stringstream hab ich nicht hinbekommen.



  • Epsylon schrieb:

    naja bei Seldons lösung muss ich extra eine neue Funktion deklarieren etc. da ist der Einzeiler doch nicht schlecht.

    Auch der Einzeiler gehört in ne eigene Funktion. Erstens kann mans dann besser lesen und zweitens ist das hier ne typische Funktion, die man irgendwann nochmal braucht. Dann fängst du an mit Copy & Paste.

    Und stringstream hab ich nicht hinbekommen.

    Das solltest du nachholen, denn stringstreams kann man öfter gebrauchen.


Anmelden zum Antworten