Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Parsing a struct with bytes

Reply
Thread Tools

Parsing a struct with bytes

 
 
ssubbarayan
Guest
Posts: n/a
 
      08-11-2008
Dear all,
I developed the following program:

void parsebytes(unsigned char* data);

struct info
{
unsigned char day;
unsigned char month;
short year;
};

struct info info1;
struct info info2;

int
main(int argc, char *argv[])
{
info1.day=12;
info1.month=8;
info1.year=2007;

parsebytes((unsigned char*)&info1);
system("PAUSE");
return EXIT_SUCCESS;
}

void parsebytes(unsigned char* data)
{
printf("day is %d\n", data[0]);
printf("month is %d\n", data[1]);
printf("year is %d\n", ((data[2] << | data[3]));
}

The above program gives proper value of 12,8 for day and month.But
year value I always get junk.What should be done to correct this and
where have I gone wrong?

Looking farward for your replies and advanced thanks,

Regards,
s.subbarayan

 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      08-11-2008
ssubbarayan <> wrote:
> I developed the following program:


> void parsebytes(unsigned char* data);


> struct info
> {
> unsigned char day;
> unsigned char month;
> short year;
> };


> struct info info1;
> struct info info2;


> int
> main(int argc, char *argv[])
> {
> info1.day=12;
> info1.month=8;
> info1.year=2007;


> parsebytes((unsigned char*)&info1);
> system("PAUSE");
> return EXIT_SUCCESS;
> }


> void parsebytes(unsigned char* data)
> {
> printf("day is %d\n", data[0]);
> printf("month is %d\n", data[1]);
> printf("year is %d\n", ((data[2] << | data[3]));
> }


> The above program gives proper value of 12,8 for day and month.But
> year value I always get junk.What should be done to correct this and
> where have I gone wrong?


There are at least two aspects that lead to problems. First
of all you can't assume that the members of a structure are
all following each other directly without any "spacing" in
between. A compiler is allowed to put as many "padding bytes"
as it want's between the members of a structure. This normally
happens due to alignement issues - some types of variables
can't start at arbitrary addresses and the compiler must make
sure that those members start at allowed addresses.

The second problem is that you make some assumptions about
the way a short int is stored in memory which might be wrong.
You assume that a short int only consists of two bytes and that
the most-significant byte is stored at a lower address than the
least-significant byte. Both assumptions can be correct on your
machine but they don't are generally correct. While a short int
requires at least two 8-bit bytes (but there are also machines
with more bits in a byte, e.g. 16 bits, so a short int may be
stored in a single byte) it can be longer. And the assumption
about the ordering of the two bytes is, assuming that two 8-bit
bytes are used, only true on big-endian machines, on many (low-
endian) machines the least-significant byte is stored at the
lower address.
Regards, Jens
--
\ Jens Thoms Toerring ___
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
 
Nick Keighley
Guest
Posts: n/a
 
      08-11-2008
On 11 Aug, 13:48, ssubbarayan <ssu...@gmail.com> wrote:

> I developed the following program:
>
> void parsebytes(unsigned char* data);
>
> struct info
> {
> *unsigned char day;
> *unsigned char month;
> *short year;
>
> };
>
> struct info info1;
> struct info info2;
>
> int
> main(int argc, char *argv[])
> {
> * * * * * * * * info1.day=12;
> * * * * info1.month=8;
> * * * * info1.year=2007;
>
> * * * * * * * *parsebytes((unsigned char*)&info1);
> * * * * * * * * system("PAUSE");
> * * * * * * * *return EXIT_SUCCESS;
>
> }
>
> void parsebytes(unsigned char* data)
> {


you missed
#include <stdlib.h>
#include <stdio.h>
at the beginning of your program

> printf("day is %d\n", data[0]);
> *printf("month is %d\n", data[1]);
> *printf("year *is %d\n", ((data[2] << | data[3]));
>
> }
>
> The above program gives proper value of 12,8 for day and month.But
> year value I always get junk.


junk? what is junk? Was it 55,047?

> What should be done to correct this


you have a struct you cast it to an array of unsigned char
and then you print the array of unsigned char. Why?

A lot of casts simply result in Undefined Behaviour
when you try and access one thing as another. The exception
is casting to unsigned char. You can cast any pointer to
an object to a pointer to unsigned char and print the unsigned chars.
But what you see is highly implementation dependent.
short is probably 2 bytes (but it doesn't have to be)
and the implementation is permitted to have them
in either order (so if I guessed the output of your
program correctly, that is how I did it).

> and where have I gone wrong?


I don't know. What are you trying to do? If you wanted
to know the internal representation of that particular struct
on your particular implementation then perhaps you did
nothing wrong.


--
Nick Keighley



 
Reply With Quote
 
Chad
Guest
Posts: n/a
 
      08-11-2008
On Aug 11, 6:25*am, Richard Heathfield <r...@see.sig.invalid> wrote:
> ssubbarayan said:
>
>
>
>
>
> > Dear all,
> > I developed the following program:

>
> > void parsebytes(unsigned char* data);

>
> > struct info
> > {
> > *unsigned char day;
> > *unsigned char month;
> > *short year;
> > };

>
> > struct info info1;
> > struct info info2;

>
> > int
> > main(int argc, char *argv[])
> > {
> > * * * * * * * * info1.day=12;
> > *info1.month=8;
> > *info1.year=2007;

>
> > * * * * * * * *parsebytes((unsigned char*)&info1);
> > * * * * * * * * system("PAUSE");
> > * * * * * * * *return EXIT_SUCCESS;
> > }

>
> > void parsebytes(unsigned char* data)
> > {
> > printf("day is %d\n", data[0]);
> > *printf("month is %d\n", data[1]);
> > *printf("year *is %d\n", ((data[2] << | data[3]));
> > }

>
> > The above program gives proper value of 12,8 for day and month.But
> > year value I always get junk.

>
> Let me guess: 55047?
>
> > What should be done to correct this and
> > where have I gone wrong?

>
> Well, the best way to correct it is to have parsebytes accept a pointer to
> an info1 structure, rather than a pointer to unsigned char.
>
> You've gone wrong in assuming that the significance of the bytes going to
> make up a short int is in decreasing order - i.e. that the most
> significant byte comes first. On some systems, that's true. On others, it
> isn't. Look up "endianness", "big-endian", "little-endian", and - would
> you believe - "middle-endian".
>
> --


How did you know that it was 55047?

 
Reply With Quote
 
Bartc
Guest
Posts: n/a
 
      08-11-2008

"Chad" <> wrote in message
news:d5246df9-8f65-4b55-a1d5-...
On Aug 11, 6:25 am, Richard Heathfield <r...@see.sig.invalid> wrote:

>> > info1.year=2007;


>> Let me guess: 55047?


> How did you know that it was 55047?


That's what you get when you swap the 2 bytes of 2007.

--
Bartc

 
Reply With Quote
 
Chad
Guest
Posts: n/a
 
      08-11-2008
On Aug 11, 8:03*am, "Bartc" <b...@freeuk.com> wrote:
> "Chad" <cdal...@gmail.com> wrote in message
>
> news:d5246df9-8f65-4b55-a1d5-...
> On Aug 11, 6:25 am, Richard Heathfield <r...@see.sig.invalid> wrote:
>
> >> > info1.year=2007;
> >> Let me guess: 55047?

> > How did you know that it was 55047?

>
> That's what you get when you swap the 2 bytes of 2007.
>


But yet

printf("day is %d\n", data[0]);
printf("month is %d\n", data[1]);

Produced the 'correct'values. Do I dare ask why.

Chad
 
Reply With Quote
 
Bartc
Guest
Posts: n/a
 
      08-11-2008
Chad wrote:
> On Aug 11, 8:03 am, "Bartc" <b...@freeuk.com> wrote:
>> "Chad" <cdal...@gmail.com> wrote in message
>>
>> news:d5246df9-8f65-4b55-a1d5-...
>> On Aug 11, 6:25 am, Richard Heathfield <r...@see.sig.invalid> wrote:
>>
>>>>> info1.year=2007;
>>>> Let me guess: 55047?
>>> How did you know that it was 55047?

>>
>> That's what you get when you swap the 2 bytes of 2007.
>>

>
> But yet
>
> printf("day is %d\n", data[0]);
> printf("month is %d\n", data[1]);
>
> Produced the 'correct'values. Do I dare ask why.


From your original post:

> struct info
> {
> unsigned char day;
> unsigned char month;
> short year;
> };


Presumably day and month are 1 byte each, and year is 2 bytes. It would be
difficult to get 1 byte in the wrong order.

Try switching the data[2] and data[3] in your code. (However this seems a
crazy way of accessing the fields of your date.)

(BTW it's now 2008 ...)

--
Bartc

 
Reply With Quote
 
ssubbarayan
Guest
Posts: n/a
 
      08-12-2008
On Aug 11, 6:14*pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
> On 11 Aug, 13:48, ssubbarayan <ssu...@gmail.com> wrote:
>
>
>
>
>
> > I developed the following program:

>
> > void parsebytes(unsigned char* data);

>
> > struct info
> > {
> > *unsigned char day;
> > *unsigned char month;
> > *short year;

>
> > };

>
> > struct info info1;
> > struct info info2;

>
> > int
> > main(int argc, char *argv[])
> > {
> > * * * * * * * * info1.day=12;
> > * * * * info1.month=8;
> > * * * * info1.year=2007;

>
> > * * * * * * * *parsebytes((unsigned char*)&info1);
> > * * * * * * * * system("PAUSE");
> > * * * * * * * *return EXIT_SUCCESS;

>
> > }

>
> > void parsebytes(unsigned char* data)
> > {

>
> you missed
> * * #include <stdlib.h>
> * * #include <stdio.h>
> at the beginning of your program
>
> > printf("day is %d\n", data[0]);
> > *printf("month is %d\n", data[1]);
> > *printf("year *is %d\n", ((data[2] << | data[3]));

>
> > }

>
> > The above program gives proper value of 12,8 for day and month.But
> > year value I always get junk.

>
> junk? what is junk? Was it 55,047?
>
> > What should be done to correct this

>
> you have a struct you cast it to an array of unsigned char
> and then you print the array of unsigned char. Why?
>
> A lot of casts simply result in Undefined Behaviour
> when you try and access one thing as another. The exception
> is casting to unsigned char. You can cast any pointer to
> an object to a pointer to unsigned char and print the unsigned chars.
> But what you see is highly implementation dependent.
> short is probably 2 bytes (but it doesn't have to be)
> and the implementation is permitted to have them
> in either order (so if I guessed the output of your
> program correctly, that is how I did it).
>
> > and where have I gone wrong?

>
> I don't know. What are you trying to do? If you wanted
> to know the internal representation of that particular struct
> on your particular implementation then perhaps you did
> nothing wrong.
>
> --
> Nick Keighley- Hide quoted text -
>
> - Show quoted text -


Hi,
Yes it prints 55047.
Regards,
s.subbarayan
 
Reply With Quote
 
ssubbarayan
Guest
Posts: n/a
 
      08-12-2008
On Aug 12, 3:14*am, "Bartc" <b...@freeuk.com> wrote:
> Chad wrote:
> > On Aug 11, 8:03 am, "Bartc" <b...@freeuk.com> wrote:
> >> "Chad" <cdal...@gmail.com> wrote in message

>
> >>news:d5246df9-8f65-4b55-a1d5-....
> >> On Aug 11, 6:25 am, Richard Heathfield <r...@see.sig.invalid> wrote:

>
> >>>>> info1.year=2007;
> >>>> Let me guess: 55047?
> >>> How did you know that it was 55047?

>
> >> That's what you get when you swap the 2 bytes of 2007.

>
> > But yet

>
> > printf("day is %d\n", data[0]);
> > *printf("month is %d\n", data[1]);

>
> > Produced the 'correct'values. Do I dare ask why.

>
> From your original post:
>
> > struct info
> > {
> > unsigned char day;
> > unsigned char month;
> > short year;
> > };

>
> Presumably day and month are 1 byte each, and year is 2 bytes. It would be
> difficult to get 1 byte in the wrong order.
>
> Try switching the data[2] and data[3] in your code. (However this seems a
> crazy way of accessing the fields of your date.)
>
> (BTW it's now 2008 ...)
>
> --
> Bartc- Hide quoted text -
>
> - Show quoted text -


Hi,
Yes it works and prints 2007,if i change data[2] and data[3] in my
code.
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      08-12-2008
On 12 Aug, 05:39, ssubbarayan <ssu...@gmail.com> wrote:
> On Aug 11, 6:14*pm,Nick Keighley<nick_keighley_nos...@hotmail.com>
> > On 11 Aug, 13:48, ssubbarayan <ssu...@gmail.com> wrote:

>
> > > I developed the following program:

>
> > > void parsebytes(unsigned char* data);

>
> > > struct info
> > > {
> > > *unsigned char day;
> > > *unsigned char month;
> > > *short year;
> > > };

>
> > > struct info info1;
> > > struct info info2;

>
> > > int
> > > main(int argc, char *argv[])
> > > {
> > > * * * * * * * * info1.day=12;
> > > * * * * info1.month=8;
> > > * * * * info1.year=2007;

>
> > > * * * * * * * *parsebytes((unsigned char*)&info1);
> > > * * * * * * * * system("PAUSE");
> > > * * * * * * * *return EXIT_SUCCESS;

>
> > > }

>
> > > void parsebytes(unsigned char* data)
> > > {

>
> > you missed
> > * * #include <stdlib.h>
> > * * #include <stdio.h>
> > at the beginning of your program

>
> > > printf("day is %d\n", data[0]);
> > > *printf("month is %d\n", data[1]);
> > > *printf("year *is %d\n", ((data[2] << | data[3]));

>
> > > }

>
> > > The above program gives proper value of 12,8 for day and month.But
> > > year value I always get junk.

>
> > junk? what is junk? Was it 55,047?

>
> > > What should be done to correct this

>
> > you have a struct you cast it to an array of unsigned char
> > and then you print the array of unsigned char. Why?

>
> > A lot of casts simply result in Undefined Behaviour
> > when you try and access one thing as another. The exception
> > is casting to unsigned char. You can cast any pointer to
> > an object to a pointer to unsigned char and print the unsigned chars.
> > But what you see is highly implementation dependent.
> > short is probably 2 bytes (but it doesn't have to be)
> > and the implementation is permitted to have them
> > in either order (so if I guessed the output of your
> > program correctly, that is how I did it).

>
> > > and where have I gone wrong?

>
> > I don't know. What are you trying to do? If you wanted
> > to know the internal representation of that particular struct
> > on your particular implementation then perhaps you did
> > nothing wrong.

>
> > --
> >Nick Keighley>


don't quote sigs (the bit after "-- ")


> Hi,
> Yes it prints 55047.


and so? Is that not what you wanted? I repeat, what are you
trying to do? What output do you want?


--
Nick Keighley
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
Could a struct with size 44 bytes point always points to a char array with size 2024 bytes? eagle_jyjh@citiz.net C++ 8 04-10-2006 03:05 PM
Could a struct with size 44 bytes point always points to a char array with size 2048 bytes? eagle_jyjh@citiz.net C Programming 5 04-09-2006 02:49 PM
Ratio of Bytes Delayed to Bytes Sent netproj Cisco 0 12-21-2005 08:08 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57