Reputation: 43
I need to convert a long int x = 0x9c758d0f
into a vector<uint8_t> y = 9c 75 8d 0f
.
I was using:
std::stringsteam ss;
ss << std::hex << x;
std::string s = ss.str();
std::vector<uint8_t> y;
String2Vector(s,y);
void String2Vector(std::string& in, std::vector<uint8_t>& output)
{
std::vector<uint8_t> out;
size_t len = in.length();
for(size_t i = 0; i < len; i += 1)
{
std::stringstream strm(in.substr(i, 1));
uint8_t x;
strm >>std::hex>> x;
out.push_back(x);
}
output = out;
}
However, the vector<uint8_t>
stored ASCII number instead of hex value.
What should I do in order to convert a long int
into a raw data vector?
It's a multi-platform project so I don't wanna touch memcpy()
etc.
Update: Pretty sure something went wrong:
long int x = 0x9c758d0f;
std::vector<uint8_t> v;
v.reserve(sizeof(x));
for (size_t i = 0; i < sizeof(x); ++i) {
v.push_back(x & 0xFF);
x = (x>>8);
}
PrintOutVector(v);
void PrintOutVector(std::vector<uint8_t>& in)
{
std::cout << "Vector Contains: ";
for(std::vector<uint8_t>::iterator i=in.begin(); i != in.end(); ++i)
std::cout << std::hex << *i ;
std::cout << "\n";
}
the output is ▒C▒▒h4
Solution: Much thanx to @WhozCraig @Anton Savin
long int x = 0x9c758d0f;
std::vector<uint8_t> v;
v.reserve(sizeof(x));
for (size_t i = 0; i < sizeof(x); ++i) {
v.push_back(x & 0xFF);
x = (x>>8);
}
PrintOutVector(v);
void PrintOutVector(std::vector<uint8_t>& in)
{
std::cout << "Vector Contains: ";
for(std::vector<uint8_t>::iterator i=in.begin(); i != in.end(); ++i)
std::cout << std::hex << static_cast<unsigned int>(*i)
std::cout << "\n";
}
Upvotes: 2
Views: 4221
Reputation: 41301
Here is a solution which provides same results regardless of byte ordering:
long int x = 0x9c758d0f;
std::vector<uint8_t> v;
v.reserve(sizeof(x));
for (size_t i = 0; i < sizeof(x); ++i) {
v.push_back(x & 0xFF);
x >>= 8;
}
Upvotes: 2
Reputation: 891
Unions come in handy for this sort of stuff. Only issue is the byte ordering might vary based on endianness, which you have to account for.
union U{
long int i;
uint8_t uc[4];
};
U u = {0x9c758d0f};
std::vector<uint8_t> ucvec(u.uc, u.uc+4);
printf ("%x:%x:%x:%x\n", ucvec[3], ucvec[2], ucvec[1], ucvec[0]);
Upvotes: 0
Reputation: 249093
long int x = 0x9c758d0f;
const uint8_t* begin = reinterpret_cast<const uint8_t*>(&x);
const uint8_t* end = begin + sizeof(x);
std::vector<uint8_t> v(begin, end);
Note that the ordering depends on how your system arranges the bytes (big endian or little endian) in the long
. You can deal with this by first reordering the bytes to big-endian with a function like htonl(), except that is for int
and there is no cross-platform one for long
so you'll have to think about what to do there if you care about the byte ordering.
Upvotes: 2