C++ 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;
}
Может кто-нибудь дать мне совет, как я могу преобразовать этот метод в C++?
7 ответов
С помощью 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;
}
Вам не нужна целая функция для этого; достаточно простого приведения:
int x;
static_cast<char*>(static_cast<void*>(&x));
Любой объект в C++ может быть интерпретирован как массив байтов. Если вы действительно хотите скопировать байты в отдельный массив, вы можете использовать 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
как массив байтов, тривиально выполнить любые необходимые изменения самостоятельно.
Вы можете получить отдельные байты с операциями anding и shift:
byte1 = nint & 0x000000ff
byte2 = (nint & 0x0000ff00) >> 8
byte3 = (nint & 0x00ff0000) >> 16
byte4 = (nint & 0xff000000) >> 24
Еще один полезный способ сделать это, я использую союзы:
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];
Это сделает так, что байтовый массив и целое число будут "перекрываться"(совместно использовать одну и ту же память). это можно сделать с любыми типами, если размер байтового массива совпадает с размером типа (иначе одно поле не будет зависеть от другого). И иметь их как один объект также просто удобно, когда вам нужно переключаться между целочисленной манипуляцией и манипулированием / копированием байтов.
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;
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;
}
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 %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);
return ((byte[0]<<24)|(byte[1]<<16)|(byte[2]<<8)|(byte[3]));
:D
Я знаю, что на этот вопрос уже есть ответы, но я дам свое решение этой проблемы. Я использую функцию шаблона и целочисленное ограничение на него.
Вот мое решение:
#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;
}
Надеюсь моя поможет
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;
}