2012-07-27 6 views
6

Eine Operation I mir durchführen müssen erfordert eine int32_t Wert und 2 int64_t Werte aus einer char Array erhaltenErhalten eines int32_t oder int64_t Wert aus einer char Array

die ersten 4 Bytes des char Array enthalten den int32 Wert, die nächsten 8 Bytes enthalten den ersten int64_t-Wert, die nächsten 8 Bytes enthalten den zweiten. Ich kann nicht herausfinden, wie ich zu diesen Werten komme. Ich habe versucht;

int32_t firstValue = (int32_t)charArray[0]; 
int64_t firstValue = (int64_t)charArray[1]; 
int64_t firstValue = (int64_t)charArray[3]; 

int32_t *firstArray = reinterpet_cast<int32_t*>(charArray); 
int32_t num = firstArray[0]; 
int64_t *secondArray = reinterpet_cast<int64_t*>(charArray); 
int64_t secondNum = secondArray[0]; 

Ich greife nur an Strohhalmen. Jede Hilfe willkommen

+0

'int32_t * first = reinterpet_cast (charArray);' sollte tatsächlich funktionieren. Es ist nicht? – Mysticial

+0

Ja, ich kann das Array tatsächlich bekommen, aber wie bekomme ich den 2. und 3. Wert? Sie sind 64 Bit. – Miek

Antwort

4

quick and dirty Lösung:

int32_t value1 = *(int32_t*)(charArray + 0); 
int64_t value2 = *(int64_t*)(charArray + 4); 
int64_t value3 = *(int64_t*)(charArray + 12); 

Beachten Sie, dass dies möglicherweise dazu führen könnte, falsch ausgerichtete Speicherzugriffe. Also funktioniert es vielleicht nicht immer.


Eine robustere Lösung, die nicht streng-Aliasing nicht verletzt und Ausrichtungsprobleme nicht haben:

int32_t value1; 
int64_t value2; 
int64_t value3; 

memcpy(&value1,charArray + 0,sizeof(int32_t)); 
memcpy(&value2,charArray + 4,sizeof(int64_t)); 
memcpy(&value3,charArray + 12,sizeof(int64_t)); 
+0

[Edsger Dijkstra genehmigt Ihre erste Lösung nicht.] (Http://www.catonmat.net/blog/wp-content/uploads/2008/11/edsger-dijkstra-quick-and-dirty.jpg) –

+0

Danke Sie sehr, die Top-Ansatz sollte meine Bedürfnisse gut und ich habe es gesehen, bevor ich jetzt sehe es wieder. – Miek

+1

@Miek Bitte beachten Sie, dass die erste Lösung vom Standard nicht garantiert wird - obwohl sie wahrscheinlich bei allen modernen Compilern mit 'sizeof (int32_t) == 4' und' sizeof (int64_t) == 8' – Mysticial

0

wenn charArray ist ein 1 Byte char Typ, dann müssen Sie 4 verwenden und 12 für 2. und 3. Werte

1

versuchen, diese

typedef struct { 
    int32_t firstValue; 
    int64_t secondValue; 
    int64_t thirdValue; 
} hd; 

hd* p = reinterpret_cast<hd*>(charArray); 

Jetzt können Sie auf die Werte z. p-> firstValue

EDIT: stellen Sie sicher, dass die Struktur an Byte-Grenzen gepackt ist, z. Mit Visual Studio schreiben Sie #pragma pack(1) vor der Struktur

+0

Dies wird nicht funktionieren wegen "struct" Auffüllen und Ausrichtung. – Mysticial

+0

dann eine Frage der Einstellung von Bound Pack zu Byte z. #pragma pack (1) –

+0

Padding kann verhindern, dass dies funktioniert ... Sie könnten '#pragma pack'-Anweisungen verwenden, aber das ist nicht zu tragbar. – dreamlax

1

Um Ausrichtungsfragen zu vermeiden, ist die ideale Lösung, die Bytes aus dem Puffer in die Zielobjekte zu kopieren. Um dies zu tun, können Sie einige hilfreiche Dienstprogramme verwenden:

typedef unsigned char const* byte_iterator; 

template <typename T> 
byte_iterator begin_bytes(T& x) 
{ 
    return reinterpret_cast<byte_iterator>(&x); 
} 

template <typename T> 
byte_iterator end_bytes(T& x) 
{ 
    return reinterpret_cast<byte_iterator>(&x + 1); 
} 

template <typename T> 
T safe_reinterpret_as(byte_iterator const it) 
{ 
    T o; 
    std::copy(it, it + sizeof(T), ::begin_bytes(o)); 
    return o; 
} 

Dann wird Ihr Problem ist einfach:

int32_t firstValue = safe_reinterpret_as<int32_t>(charArray); 
int64_t secondValue = safe_reinterpret_as<int64_t>(charArray + 4); 
int64_t thirdValue = safe_reinterpret_as<int64_t>(charArray + 12); 
Verwandte Themen