2016-05-08 32 views
0

Gibt es eine Möglichkeit, eine std::bitset aus einer hexadezimalen std::string oder QString und umgekehrt, ohne eine binäre Verschiebeoperationen zu konstruieren? Ich weiß, wie man das macht, aber ich frage mich, ob es möglich ist, dies mit C++ - Streams oder etwas Ähnlichem zu tun.erstellen std :: bitset oder QBitArray von einer std :: string oder QString enthält hexadezimale Zahlen

hier ist mein Code so weit (versuchen, kommt unter Beschuss von Moderatoren zu vermeiden):

QString data("aabbccddeeff"); 
QByteArray temp = QByteArray::fromHex(data.simplified().toLatin1()); 
QBitArray bits(temp.count()*8); 
for(int i=0; i<temp.count(); ++i) { 
    for(int b=0; b<8;b++) { 
     bits.setBit(i*8+b, temp.at(i)&(1<<(7-b))); 
    } 
} 
+0

Was ist die maximale Länge der resultierenden Bits? Ist es länger als die breiteste Ganzzahl auf Ihrer Plattform? –

+0

@JohnZwinck es ist 128 Bits oder 16 Bytes max. – Barracuda

Antwort

1

Sie könnten das Hex-String zu einem integralen konvertieren, und eine bitset aus, dass konstruieren.

#include <iostream> 
#include <sstream> 
#include <bitset> 
#include <string> 

using namespace std; 

int main() 
{ 
    string s = "0xA"; 
    stringstream ss; 
    ss << hex << s; 
    unsigned n; 
    ss >> n; 
    bitset<32> b(n); 
    // outputs "00000000000000000000000000001010" 
    cout << b.to_string() << endl; 
} 
+0

'ss >> n' initialisiert 'n' mit ASCII-Wert des Zeichens, das' ss' durch die Zeile 'ss << hex << s' geliefert wird. – Barracuda

0

basierend auf Antwort unten durch Trevor zur Verfügung gestellt, schrieb ich den folgenden Code:

std::vector<std::bitset<8ul> > Bytes2Bits(QByteArray bytes) 
{ 
    std::vector<std::bitset<8ul> > v; 
    for(int i = 0 ; i < bytes.size(); ++i) 
    { 
     QByteArray temp; 
     temp.append(bytes.at(i)); 
     std::string s = temp.toHex().toStdString(); 
     std::stringstream ss; 
     ss << s; 
     int n; 
     ss >> n; 
     std::bitset<8ul> b(n); 
     v.push_back(b); 
    } 
    return v; 
} 

Ich hoffe, dass es für andere nützlich ist die gleiche Lösung zu suchen.

0

Wie wäre es damit?

std::string str("deadBEEF"); 
std::bitset<128> bits; // result 

char* raw = reinterpret_cast<char*>(&bits) + sizeof(bits) - 1; // last byte           
assert(str.size() <= 2 * sizeof(bits)); 

for (size_t ii = 0; ii < str.size(); ++ii) { 
    char ch = str[ii]; 

    if (ch >= '0' && ch <= '9') { 
     ch -= '0'; 
    } else if (ch >= 'a' && ch <= 'f') { 
     ch -= 'a' - 10; 
    } else if (ch >= 'A' && ch <= 'F') { 
     ch -= 'A' - 10; 
    } else { 
     throw std::runtime_error("invalid input"); 
    } 

    if (ii % 2 == 0) { 
     ch <<= 4; // nibble                       
    } 

    *raw |= ch; 

    if (ii % 2) { 
     --raw; 
    } 
} 

cout << bits << endl; 

Die oben geht davon aus, dass ein std::bitset hat genau ein Datenelement: ein Array von ganzen Zahlen groß genug, um die Anzahl von Bits als Templat zu halten. Ich denke, das ist eine faire Annahme, aber es ist sicherlich nicht tragbar. Die gute Nachricht ist, dass es schnell geht - teilweise weil es keine dynamische Speicherzuweisung macht.