How to concatinate 32bits of 4 bytes in a char array, and assigning to an int?

N

Noel Milton

Hi:

Ok, I've just read in up to 65,535 bytes into a char array (using the
recvfrom socket API
call). So I have an array of 8 bit char's (char recvString[ ];).

Now, four (4) consecutive bytes somewhere within that array represent a
counter.

How can I take those 4 individual bytes, concatinate the 32bits that
make up those
4 bytes, and assign them to "unsigned int i;". In other words, those
32bits represent
an unsigned counter, and I need to transfer them out of the array, make
an integer out
of those 32bits (8x4) and assign them to "unsigned int i", so I can
then perform some
simple math.

I've tried various methods with no luck and my problem may be
big/little endian.

Does any have portable code snippes for doing this (that won't break
when the
sizeof something chages for example, etc).

Regards,
Noelle Milton Vega
(e-mail address removed)
 
F

Frank Silvermann

Noel said:
Hi:

Ok, I've just read in up to 65,535 bytes into a char array (using the
recvfrom socket API
call). So I have an array of 8 bit char's (char recvString[ ];).
I'd ask whence char recvString[] came, but I suspect it didn't come from
standard C.
Now, four (4) consecutive bytes somewhere within that array represent a
counter.

How can I take those 4 individual bytes, concatinate the 32bits that
make up those
4 bytes, and assign them to "unsigned int i;". In other words, those
32bits represent
an unsigned counter, and I need to transfer them out of the array, make
an integer out
of those 32bits (8x4) and assign them to "unsigned int i", so I can
then perform some
simple math.

I've tried various methods with no luck and my problem may be
big/little endian.

Does any have portable code snippes for doing this (that won't break
when the
sizeof something chages for example, etc).
Since representation can be many and varied, I think you're going to
have to cook from scratch. frank
 
N

Noel Milton

Hello Frank:

You might be right. I've tried many (and I mean many) variations of the
following
where I altered the format part of the string, with no luck... but I
think

unsigned int i;
-or-
unsigned char intBits[4 or 5];
snprintf/sprintf(intBits, 4, "%02hhu%02hhu%02hhu%02hhu",
*(recvString + 10),
*(recvString + 11),
*(recvString + 12),
*(recvString + 13));

But it could be that 12 & 13 should come before 10 & 11 (big/little
endian) or
even 13/12/11/10 (the complete reverse).
In the case of using char intBits[], I then tried something like i =
(int) *intBits;
And all kinds of stuff.

Do you think bit shifting and masking approach is better (or someother
approach)?

Regards.

Frank said:
Noel said:
Hi:

Ok, I've just read in up to 65,535 bytes into a char array (using the
recvfrom socket API
call). So I have an array of 8 bit char's (char recvString[ ];).
I'd ask whence char recvString[] came, but I suspect it didn't come from
standard C.
Now, four (4) consecutive bytes somewhere within that array represent a
counter.

How can I take those 4 individual bytes, concatinate the 32bits that
make up those
4 bytes, and assign them to "unsigned int i;". In other words, those
32bits represent
an unsigned counter, and I need to transfer them out of the array, make
an integer out
of those 32bits (8x4) and assign them to "unsigned int i", so I can
then perform some
simple math.

I've tried various methods with no luck and my problem may be
big/little endian.

Does any have portable code snippes for doing this (that won't break
when the
sizeof something chages for example, etc).
Since representation can be many and varied, I think you're going to
have to cook from scratch. frank
 
B

bert

Noel said:
Hello Frank:

You might be right. I've tried many (and I mean many) variations of the
following
where I altered the format part of the string, with no luck... but I
think

unsigned int i;
-or-
unsigned char intBits[4 or 5];
snprintf/sprintf(intBits, 4, "%02hhu%02hhu%02hhu%02hhu",
*(recvString + 10),
*(recvString + 11),
*(recvString + 12),
*(recvString + 13));

But it could be that 12 & 13 should come before 10 & 11 (big/little
endian) or
even 13/12/11/10 (the complete reverse).
In the case of using char intBits[], I then tried something like i =
(int) *intBits;
And all kinds of stuff.

Do you think bit shifting and masking approach is better (or someother
approach)?

Oh, dear. Your sprintf would deposit DISPLAY characters
into your intBits[ ] array, but you want BINARY characters
exactly as they already are in recvString[ ].

Try something like this:

int i = ((recvString[10] * 256 + recvString[11]) * 256
+ recvString[12]) * 256 + recvString[13];
and juggle the subscripts until it's right.
--
 
E

Eric Sosman

Noel Milton wrote On 06/08/06 13:25,:
Hi:

Ok, I've just read in up to 65,535 bytes into a char array (using the
recvfrom socket API
call). So I have an array of 8 bit char's (char recvString[ ];).

Now, four (4) consecutive bytes somewhere within that array represent a
counter.

How can I take those 4 individual bytes, concatinate the 32bits that
make up those
4 bytes, and assign them to "unsigned int i;". In other words, those
32bits represent
an unsigned counter, and I need to transfer them out of the array, make
an integer out
of those 32bits (8x4) and assign them to "unsigned int i", so I can
then perform some
simple math.

First, use a buffer of `unsigned char' instead of
plain `char'. Plain `char' may be either signed or
unsigned at the implementation's whim, and you don't
want negative byte values making things complicated.

Next, suppose that the four bytes of interest are
at positions [n] through [n+3]. If they are arranged in
big-endian order (most significant at [n]), use

i = 256u * 256u * 256u * buf[n]
+ 256u * 256u * buf[n+1]
+ 256u * buf[n+2]
+ buf[n+3];

If they are arranged in little-endian order (least
significant at [n]), turn the indices around and use

i = 256u * 256u * 256u * buf[n+3]
+ 256u * 256u * buf[n+2]
+ 256u * buf[n+1]
+ buf[n];

If they are arranged in some more exotic order (there
are 24 possibilities in all, and at least three have
actually been used), just multiply each byte's value
by the corresponding power of 256 -- just think of the
value as a four-digit number written in base 256, and
all should become clear.

There are, of course, many ways to write the expressions
above. The way I've chosen assumes an `unsigned int' of 32
or more bits, while C itself only promises 16 or more; you
could use 256ul throughout to change to `unsigned long'.
Also, the expressions above are careful to avoid potential
confusions between `int' and `unsigned int'; if you choose
to rewrite using shift operators, for example, be careful
about unintended promotions to signed `int'.
 
N

Noel Milton

Thanks Bert... Love the "Oh dear" part LOL. I did try stripping '\0'
and other
artifacts, but, as you alluded, these are the annoyances with this
method.

Your proposal sounds better. In fact, I was going the take each 4bit
hex char and
perform hex to dec math to get the value (e.g. ((a1*16 + a2)*16 +
a3)*16 +a4 ...
and so on), but yours is better because its on a byte-by-byte
basis, versus on a 4 bit hex-by-hex basis, so half as many
calculations.

Btw... nice use, of algebraic precedence (always nice to see).

Regards
 
N

Noel Milton

Thaks Eric... your and Bert's examples (the same algorithmically),
is what I was looking for. Appreciate the time for the lengthy
expansion Eric. Regards Bert/Eric.

Eric said:
Noel Milton wrote On 06/08/06 13:25,:
Hi:

Ok, I've just read in up to 65,535 bytes into a char array (using the
recvfrom socket API
call). So I have an array of 8 bit char's (char recvString[ ];).

Now, four (4) consecutive bytes somewhere within that array represent a
counter.

How can I take those 4 individual bytes, concatinate the 32bits that
make up those
4 bytes, and assign them to "unsigned int i;". In other words, those
32bits represent
an unsigned counter, and I need to transfer them out of the array, make
an integer out
of those 32bits (8x4) and assign them to "unsigned int i", so I can
then perform some
simple math.

First, use a buffer of `unsigned char' instead of
plain `char'. Plain `char' may be either signed or
unsigned at the implementation's whim, and you don't
want negative byte values making things complicated.

Next, suppose that the four bytes of interest are
at positions [n] through [n+3]. If they are arranged in
big-endian order (most significant at [n]), use

i = 256u * 256u * 256u * buf[n]
+ 256u * 256u * buf[n+1]
+ 256u * buf[n+2]
+ buf[n+3];

If they are arranged in little-endian order (least
significant at [n]), turn the indices around and use

i = 256u * 256u * 256u * buf[n+3]
+ 256u * 256u * buf[n+2]
+ 256u * buf[n+1]
+ buf[n];

If they are arranged in some more exotic order (there
are 24 possibilities in all, and at least three have
actually been used), just multiply each byte's value
by the corresponding power of 256 -- just think of the
value as a four-digit number written in base 256, and
all should become clear.

There are, of course, many ways to write the expressions
above. The way I've chosen assumes an `unsigned int' of 32
or more bits, while C itself only promises 16 or more; you
could use 256ul throughout to change to `unsigned long'.
Also, the expressions above are careful to avoid potential
confusions between `int' and `unsigned int'; if you choose
to rewrite using shift operators, for example, be careful
about unintended promotions to signed `int'.
 
C

CBFalconer

Noel said:
You might be right. I've tried many (and I mean many) variations
of the following where I altered the format part of the string,
with no luck... but I think

unsigned int i;
-or-
unsigned char intBits[4 or 5];
.... snip ...

Don't toppost. Your reply belongs after, or intermixed with, the
material to which you reply, after snipping anything not germane to
your reply.

--
"Our enemies are innovative and resourceful, and so are we.
They never stop thinking about new ways to harm our country
and our people, and neither do we." -- G. W. Bush.
"The people can always be brought to the bidding of the
leaders. All you have to do is tell them they are being
attacked and denounce the pacifists for lack of patriotism
and exposing the country to danger. It works the same way
in any country." --Hermann Goering.
 
F

Frank Silvermann

Eric said:
Noel Milton wrote On 06/08/06 13:25,:

[OP has 4 bytes and wants an int]
First, use a buffer of `unsigned char' instead of
plain `char'. Plain `char' may be either signed or
unsigned at the implementation's whim, and you don't
want negative byte values making things complicated.

Next, suppose that the four bytes of interest are
at positions [n] through [n+3]. If they are arranged in
big-endian order (most significant at [n]), use

i = 256u * 256u * 256u * buf[n]
+ 256u * 256u * buf[n+1]
+ 256u * buf[n+2]
+ buf[n+3];

If they are arranged in little-endian order (least
significant at [n]), turn the indices around and use

i = 256u * 256u * 256u * buf[n+3]
+ 256u * 256u * buf[n+2]
+ 256u * buf[n+1]
+ buf[n];

If they are arranged in some more exotic order (there
are 24 possibilities in all, and at least three have
actually been used), just multiply each byte's value
by the corresponding power of 256 -- just think of the
value as a four-digit number written in base 256, and
all should become clear.
24 = 4!
There are, of course, many ways to write the expressions
above. The way I've chosen assumes an `unsigned int' of 32
or more bits, while C itself only promises 16 or more; you
could use 256ul throughout to change to `unsigned long'.
Also, the expressions above are careful to avoid potential
confusions between `int' and `unsigned int'; if you choose
to rewrite using shift operators, for example, be careful
about unintended promotions to signed `int'.
I see no a priori reason to think his bits were going to add up to a
byte in any meaningful way. There is no guarantee that the non Standard
methods will be common sensical in this respect. Your post is an
example of the type I print out and put into my notebook for hard-copy
perusal at the cafe. frank
 

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,048
Latest member
verona

Latest Threads

Top