Reputation: 4573
Suppose, I wanted to write decimal 31 in a binary file (which is already loaded into vector) in 4 bytes so I have to write as 00 00 00 1f, but I don't know how to convert decimal number in hex string (of 4 bytes)
So, expected hex in vector of unsigned char is:
0x00 0x00 0x00 0x1f // int value of this is 31
To do this I tried following:
std::stringstream stream;
stream << std::setfill('0') << std::setw(sizeof(int) * 2) << std::hex << 31;
cout << stream.str();
Output:
0000001f
Above line of code gives output in string format but I want it into vector of unsigned char in format of '0x', so my output vector should have elements after conversion as 0x00 0x00 0x00 0x1F.
Upvotes: 1
Views: 1039
Reputation: 409166
Without bothering with endianness you could copy the int
value into a character buffer of the appropriate size. This buffer could be the vector itself.
Perhaps something like this:
std::vector<uint8_t> int_to_vector(unsigned value)
{
// Create a vector of unsigned characters (bytes on a byte-oriented platform)
// The size will be set to the same size as the value type
std::vector<uint8_t> buffer(sizeof value);
// Do a byte-wise copy of the value into the vector data
std::memcpy(buffer.data(), &value, sizeof value);
return buffer;
}
The order of bytes in the vector will always in the host native order. If a specific order is mandated then each byte of the multi-byte value needs to be copied into a specific element of the array using bitwise operations (std::memcpy
can't be used).
Also note that this function will break strict aliasing if uint8_t
isn't an alias of unsigned char
. And that uint8_t
is an optional type, there are platforms which doesn't have 8-bit entities (though they are not common).
For an endianness-specific variant, where each value of a byte is extracted one by one and added to the vector, perhaps something like this:
std::vector<uint8_t> int_to_be_vector(unsigned value)
{
// Create a vector of unsigned characters (bytes on a byte-oriented platform)
// The size will be set to the same size as the value type
std::vector<uint8_t> buffer(sizeof value);
// For each byte in the multi-byte value, copy it to the "correct" place in the vector
for (size_t i = buffer.size(); i > 0; --i)
{
// The cast truncates the value, dropping all but the lowest eight bits
buffer[i - 1] = static_cast<uint8_t>(value);
value >>= 8;
}
return buffer;
}
Upvotes: 4
Reputation: 941
You could use a loop to extract one byte at a time of the original number and store that in a vector.
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <vector>
using u8 = std::uint8_t;
using u32 = std::uint32_t;
std::vector<u8> GetBytes(const u32 number) {
const u32 mask{0xFF};
u32 remaining{number};
std::vector<u8> result{};
while (remaining != 0u) {
const u32 bits{remaining & mask};
const u8 res{static_cast<u8>(bits)};
result.push_back(res);
remaining >>= 8u;
}
std::reverse(std::begin(result), std::end(result));
return result;
}
int main() {
const u32 myNumber{0xABC123};
const auto bytes{GetBytes(myNumber)};
std::cout << std::hex << std::showbase;
for (const auto b : bytes) {
std::cout << static_cast<u32>(b) << ' ';
}
std::cout << std::endl;
return 0;
}
The output of this program is:
0xab 0xc1 0x23
Upvotes: 1