简体   繁体   中英

Convert Integer to 4 byte ungisned char vector (in Big endian byte order)

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.

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

Example of it working

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM