Obtain padded string containing number in hex form

E

Eric Lilja

Hello, I have an unsigned long that I need to convert to a std::string.
The unsigned long holds 32-bit checksums and sometimes the most
significant byte is 0 and in those cases the string should be zero
padded (it should always contain 8 chars) and it should display its
value in hex form without 0x in the beginning. So if the unsigned long
holds the value 0xa87d7d4 the string should contain "0a87d7d4".
I tried a combination of iomanip and stringstreams but this code
snippet still yields a string containing a decimal number (and I'm not
sure my 0-padding is working either):
std::string s;
std::stringstream ss;
ss << crc32; // crc32 is of type unsigned long
ss >> std::setw(8) >> std::hex >> s;

I guess I could read the checksum four bits at a time converting each
bit group into the corresponding hexadecimal number and gradually build
the string, but I wanted to ask you experts if there was a neater way
involving the standard library first.

/ E
 
E

Eric Lilja

Eric said:
Hello, I have an unsigned long that I need to convert to a std::string.
The unsigned long holds 32-bit checksums and sometimes the most
significant byte is 0 and in those cases the string should be zero
padded (it should always contain 8 chars) and it should display its
value in hex form without 0x in the beginning. So if the unsigned long
holds the value 0xa87d7d4 the string should contain "0a87d7d4".
I tried a combination of iomanip and stringstreams but this code
snippet still yields a string containing a decimal number (and I'm not
sure my 0-padding is working either):
std::string s;
std::stringstream ss;
ss << crc32; // crc32 is of type unsigned long
ss >> std::setw(8) >> std::hex >> s;

I guess I could read the checksum four bits at a time converting each
bit group into the corresponding hexadecimal number and gradually build
the string, but I wanted to ask you experts if there was a neater way
involving the standard library first.

I solved it using sprintf. This program shows how:
#include <cstdio>
#include <iostream>

int
main()
{
unsigned long l = 0x0a87d7d4;
char buffer[9];

// %[flags][width][.precision][modifiers]type
// type = lx = Unsigned long hexadecimal integer
// flags =none
// width = 08

std::sprintf(buffer, "%08lx", l);

std::cout << buffer << std::endl;

return 0;
}

Output:
$ ./conv.exe
0a87d7d4

But I still would like to know how to solve it using streams too, for
learning purposes.

/ E
 
J

Jerry Coffin

Hello, I have an unsigned long that I need to convert to a std::string.
The unsigned long holds 32-bit checksums and sometimes the most
significant byte is 0 and in those cases the string should be zero
padded (it should always contain 8 chars) and it should display its
value in hex form without 0x in the beginning. So if the unsigned long
holds the value 0xa87d7d4 the string should contain "0a87d7d4".
I tried a combination of iomanip and stringstreams but this code
snippet still yields a string containing a decimal number (and I'm not
sure my 0-padding is working either):

#include <iomanip>
#include <sstream>
#include <iostream>

int main() {

unsigned crc32 = 0xa87d7d4;
std::stringstream ss;
std::string s;

ss << std::hex << std::setfill('0')
<< std::setw(8) << std::setprecision(8)
<< crc32;

// _obviously_ better than '%8.8x'

s = ss.str();
std::cout << s << std::endl;
return 0;
}
 
E

Eric Lilja

Jerry said:
#include <iomanip>
#include <sstream>
#include <iostream>

int main() {

unsigned crc32 = 0xa87d7d4;
std::stringstream ss;
std::string s;

ss << std::hex << std::setfill('0')
<< std::setw(8) << std::setprecision(8)
<< crc32;

// _obviously_ better than '%8.8x'

s = ss.str();
std::cout << s << std::endl;
return 0;
}

Seems to work just fine, thanks Jerry! Now I know how to do it using
both C++ streams and C style.

/ E
 
A

ax

#include <iomanip>
#include <sstream>
#include <iostream>

int main() {

unsigned crc32 = 0xa87d7d4;
std::stringstream ss;
std::string s;

ss << std::hex << std::setfill('0')
<< std::setw(8) << std::setprecision(8)
<< crc32;

don't will be better:?

cout << (ss << fmt("0x%8x", '0') << crc32);
 
J

Jerry Coffin

[ ... ]
don't will be better:?

cout << (ss << fmt("0x%8x", '0') << crc32);

If you have the 'fmt' function available, and it does what it looks
like it would above, it may be quite useful. But be aware that it's
not part of the standard library, nor even part of TR1, so it's not
what you'd usually think of as particularly portable.
 
D

Duane Hebert

If you have the 'fmt' function available, and it does what it looks
like it would above, it may be quite useful. But be aware that it's
not part of the standard library, nor even part of TR1, so it's not
what you'd usually think of as particularly portable.

Is boost::format part of TR1? At any rate, it may be a useful
alternative here.
 
J

Jerry Coffin

[ ... ]
Is boost::format part of TR1?

I'd have to re-check to be absolutely sure, but I don't think so.
At any rate, it may be a useful alternative here.

Quite true -- there are quite a few alternatives, but I don't believe
any of them has been standardized.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top