С++ int в байтовый массив

Вопрос:У меня есть этот метод в моем java-коде, который возвращает массив байтов для заданного int: 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; } Может кто-нибудь дать мне совет, как я

Вопрос:

У меня есть этот метод в моем java-коде, который возвращает массив байтов для заданного int:

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; }

Может кто-нибудь дать мне совет, как я могу преобразовать этот метод в С++?

Лучший ответ:

Использование 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; } Ответ №1

Для этого вам не нужна целая функция; достаточно простого приведения:

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

Любой объект в С++ может быть переинтерпретирован как массив байтов. Если вы хотите сделать копию байтов в отдельный массив, вы можете использовать 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);

Ни один из этих методов не учитывает порядок байтов, но поскольку вы можете переосмыслить int как массив байтов, тривиально самостоятельно выполнить любые необходимые изменения.

Ответ №2

Другим полезным способом сделать это, который я использую, является объединение:

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];

Это приведет к тому, что массив байтов и целое число будет “перекрываться” (совместно использовать одну и ту же память).
это может быть сделано со всеми типами типов, если массив байтов имеет тот же размер, что и тип (иначе одно из полей не будет влиять на другое). И иметь их как один объект также удобно, когда вам нужно переключаться между целыми манипуляциями и манипулированием байтами/копированием.

Ответ №3

Вы можете получить отдельные байты с операциями anding и shifting:

byte1 = nint & 0x000000ff byte2 = (nint & 0x0000ff00) >> 8 byte3 = (nint & 0x00ff0000) >> 16 byte4 = (nint & 0xff000000) >> 24 Ответ №4std::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; } Ответ №5

Int в байт и наоборот.

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 %xn», 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); Ответ №6

Int (или любой другой тип данных в этом отношении) уже хранится как байты в памяти. Так почему бы просто не скопировать память напрямую?

memcpy(arrayOfByte, &x, sizeof x);

Простой элегантный лайнер, который также будет работать с любым другим типом данных.

Если вам нужно поменять местами байты, вы можете использовать std::reverse

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

или еще лучше, просто скопируйте байты в обратном порядке, чтобы начать с

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

Если вы вообще не хотите делать копию данных, а просто имеете их байтовое представление

BYTE* bytes = (BYTE*) &x; Ответ №7return ((byte[0]<<24)|(byte[1]<<16)|(byte[2]<<8)|(byte[3]));

: D

Ответ №8

Я знаю, что на этот вопрос уже есть ответы, но я дам свое решение этой проблемы. Я использую функцию шаблона и целочисленное ограничение на него.

Вот мое решение:

#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; } Ответ №9

Я надеюсь, что мое поможет

template <typename t_int> std::array<uint8_t, sizeof (t_int)> int2array(t_int p_value) { static const uint8_t _size_of (static_cast<uint8_t>(sizeof (t_int))); typedef std::array<uint8_t, _size_of> buffer; static const std::array<uint8_t, 8> _shifters = {8*0, 8*1, 8*2, 8*3, 8*4, 8*5, 8*6, 8*7}; buffer _res; for (uint8_t _i=0; _i < _size_of; ++_i) { _res[_i] = static_cast<uint8_t>((p_value >> _shifters[_i])); } return _res; }

Оцените статью
Добавить комментарий