web-dev-qa-db-fra.com

C++ int à tableau d'octets

J'ai cette méthode dans mon code Java qui renvoie un tableau d'octets pour int donné:

private static byte[] intToBytes(int paramInt)
{
     byte[] arrayOfByte = new byte[4];
     ByteBuffer localByteBuffer = ByteBuffer.allocate(4);
     localByteBuffer.putInt(paramInt);
     for (int i = 0; i < 4; i++)
         arrayOfByte[(3 - i)] = localByteBuffer.array()[i];
     return arrayOfByte;
}

Quelqu'un peut-il me donner un conseil, comment puis-je convertir cette méthode en C++?

22
justme_

Utiliser std::vector<unsigned char>:

#include <vector>
using namespace std;

vector<unsigned char> intToBytes(int paramInt)
{
     vector<unsigned char> arrayOfByte(4);
     for (int i = 0; i < 4; i++)
         arrayOfByte[3 - i] = (paramInt >> (i * 8));
     return arrayOfByte;
}
18
Donotalo

Vous n'avez pas besoin de toute une fonction pour cela; un simple casting suffira:

int x;
static_cast<char*>(static_cast<void*>(&x));

Tout objet en C++ peut être réinterprété en tant que tableau d'octets. Si vous voulez réellement faire une copie des octets dans un tableau séparé, vous pouvez utiliser std::copy:

int x;
char bytes[sizeof x];
std::copy(static_cast<const char*>(static_cast<const void*>(&x)),
          static_cast<const char*>(static_cast<const void*>(&x)) + sizeof x,
          bytes);

Aucune de ces méthodes ne prend en compte l'ordre des octets, mais comme vous pouvez réinterpréter la variable int sous la forme d'un tableau d'octets, il est simple de procéder à toute modification nécessaire.

46
James McNellis

Une autre manière utile de le faire est d’utiliser les syndicats:

union byteint
{
    byte b[sizeof int];
    int i;
};
byteint bi;
bi.i = 1337;
for(int i = 0; i<4;i++)
    destination[i] = bi.b[i];

Cela fera en sorte que le tableau d'octets et l'entier "se chevauchent" (partagent la même mémoire) . Ceci peut être fait avec toutes sortes de types, tant que le tableau d'octets a la même taille que le type sinon l'un des champs ne sera pas influencé par l'autre). Et les avoir comme un seul objet est également pratique lorsque vous devez basculer entre la manipulation d’entiers et la manipulation/copie d’octets.

12
NullData

Int à octet et vice versa.  

unsigned char bytes[4];
unsigned long n = 1024;

bytes[0] = (n >> 24) & 0xFF;
bytes[1] = (n >> 16) & 0xFF;
bytes[2] = (n >> 8) & 0xFF;
bytes[3] = n & 0xFF;

printf("%x %x %x %x\n", bytes[0], bytes[1], bytes[2], bytes[3]);


int num = 0;
for(int i = 0; i < 4; i++)
 {
 num <<= 8;
 num |= bytes[i];
 }


printf("number %d",num);
5
Sarath AK

Vous pouvez obtenir des octets individuels avec les opérations anding et shifting:

byte1 =  nint & 0x000000ff
byte2 = (nint & 0x0000ff00) >> 8
byte3 = (nint & 0x00ff0000) >> 16
byte4 = (nint & 0xff000000) >> 24
5
BlackBear
std::vector<unsigned char> intToBytes(int value)
{
    std::vector<unsigned char> result;
    result.Push_back(value >> 24);
    result.Push_back(value >> 16);
    result.Push_back(value >>  8);
    result.Push_back(value      );
    return result;
}
4
James Kanze
return ((byte[0]<<24)|(byte[1]<<16)|(byte[2]<<8)|(byte[3]));

:RÉ

2
jberg

Un int (ou tout autre type de données) est déjà stocké sous forme d'octets en mémoire. Alors pourquoi ne pas simplement copier la mémoire directement?

memcpy(arrayOfByte, &x, sizeof x);

Un simple liner élégant qui fonctionnera également avec tout autre type de données.



Si vous avez besoin d'inverser les octets, vous pouvez utiliser std :: reverse

memcpy(arrayOfByte, &x, sizeof x);
std::reverse(arrayOfByte, arrayOfByte + sizeof x);

ou mieux encore, copiez simplement les octets en sens inverse pour commencer

BYTE* p = (BYTE*) &x;
std::reverse_copy(p, p + sizeof x, arrayOfByte);

Si vous ne voulez pas du tout copier les données et simplement avoir leur représentation sous forme d'octet

BYTE* bytes = (BYTE*) &x;
2
SportySpice

Je sais que cette question a déjà des réponses, mais je vais donner ma solution à ce problème. J'utilise la fonction de modèle et la contrainte entière sur celle-ci.

Voici ma solution:

#include <type_traits>
#include <vector>

template <typename T,
          typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
std::vector<uint8_t> splitValueToBytes(T const& value)
{
    std::vector<uint8_t> bytes;

    for (size_t i = 0; i < sizeof(value); i++)
    {
        uint8_t byte = value >> (i * 8);
        bytes.insert(bytes.begin(), byte);
    }

    return bytes;
}
0
NutCracker