views:

1859

answers:

5

I want to take the value stored in a 32 bit unsigned int, put it into four chars and then store the integer value of each of these chars in a string.

I think the first part goes like this:

char a = orig << 8;
char b = orig << 8;
char c = orig << 8;
char d = orig << 8;
+1  A: 

Not quite:

char a = orig & 0xff;
orig >>= 8;
char b = orig & 0xff;
orig >>= 8;
char c = orig & 0xff;
orig >>= 8;
char d = orig & 0xff;

Not exactly sure what you mean by "store the integer values of each of these values into a string. Do you want turn 0x10111213 into "16 17 18 19", or what?

Paul Tomblin
Once I have the chars, I want to print their integer value
Clayton
@Clayton, restating the question in exactly the same words in a slightly different order isn't what I call "clarification"
Paul Tomblin
A: 

For hexadecimal:

sprintf(buffer, "%lX", orig);

For decimal:

sprintf(buffer, "%ld", orig);

Use snprintf to avoid a buffer overflow.

Ates Goral
Or use the stream operators. This was tagged a C++ question.
Martin York
+4  A: 

Use a union. (As requested here is the sample program.)

    #include <<iostream>>
    #include <<stdio.h>>
    using namespace std;

    union myunion
    {
       struct chars 
       { 
          unsigned char d, c, b, a;
       } mychars;

        unsigned int myint; 
    };

    int main(void) 
    {
        myunion u;

        u.myint = 0x41424344;

        cout << "a = " << u.mychars.a << endl;
        cout << "b = " << u.mychars.b << endl;
        cout << "c = " << u.mychars.c << endl;
        cout << "d = " << u.mychars.d << endl;
    }

As James mentioned this is platform specific.

Vivek
The problem with doing it like that is you'd get different results on systems with different endianness.
James Sutherland
A good start. Now exhibit how to use it. Upvoted.
dmckee
+10  A: 

Let's say "orig" is a 32bit variable containing your value.

I imagine you want to do something like this:

unsigned char byte1=orig&0xff;
unsigned char byte2=(orig>>8)&0xff;
unsigned char byte3=(orig>>16)&0xff;
unsigned char byte4=(orig>>24)&0xff;

char myString[256];
sprintf(myString,"%x %x %x %x",byte1,byte2,byte3,byte4);

I'm not sure this is always endian correct, by the way. (Edit: indeed, it is endian correct, since bitshift operations shouldn't be affected by endianness)

Hope this helps.

friol
This will give you the same answer on big and little-endian machines.
tgamblin
You probably want to use "%d %d %d %d" or "%x %x %x %x" in that format string.
Ates Goral
+10  A: 

If you really want to extract the individual bytes first:

unsigned char a = orig & 0xff;
unsigned char b = (orig >> 8) & 0xff;
unsigned char c = (orig >> 16) & 0xff;
unsigned char d = (orig >> 24) & 0xff;

Or:

unsigned char *chars = (unsigned char *)(&orig);
unsigned char a = chars[0];
unsigned char b = chars[1];
unsigned char c = chars[2];
unsigned char d = chars[3];

Or use a union of an unsigned long and four chars:

union charSplitter {
    struct {
        unsigned char a, b, c, d;
    } charValues;

    unsigned int intValue;
};

charSplitter splitter;
splitter.intValue = orig;
// splitter.charValues.a will give you first byte etc.

Update: as friol pointed out, solutions 2 and 3 are not endianness-agnostic; which bytes a, b, c and d represent depend on the CPU architecture.

Ates Goral
Solutions 2 and 3 are not endian correct (they would give different result on different machines).
friol