473,322 Members | 1,496 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Parsing a struct with bytes

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] << 8) | 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

Aug 11 '08 #1
6 1666
ssubbarayan <ss****@gmail.comwrote:
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] << 8) | 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 ___ jt@toerring.de
\__________________________ http://toerring.de
Aug 11 '08 #2

"Chad" <cd*****@gmail.comwrote in message
news:d5**********************************@r35g2000 prm.googlegroups.com...
On Aug 11, 6:25 am, Richard Heathfield <r...@see.sig.invalidwrote:
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

Aug 11 '08 #3
On Aug 11, 8:03*am, "Bartc" <b...@freeuk.comwrote:
"Chad" <cdal...@gmail.comwrote in message

news:d5**********************************@r35g2000 prm.googlegroups.com...
On Aug 11, 6:25 am, Richard Heathfield <r...@see.sig.invalidwrote:
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
Aug 11 '08 #4
Chad said:
On Aug 11, 8:03 am, "Bartc" <b...@freeuk.comwrote:
>"Chad" <cdal...@gmail.comwrote in message

news:d5**********************************@r35g2000 prm.googlegroups.com...
>On Aug 11, 6:25 am, Richard Heathfield <r...@see.sig.invalidwrote:
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.
info1.day and info1.month are unsigned chars, which are by definition a
single byte wide. It's tricky to get a single byte the wrong way round.
(Yes, it can be done, with practice - but it's tricky.)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 11 '08 #5
ssubbarayan <ss****@gmail.comwrites:
On Aug 12, 12:50Â*pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
<snip>
>and so? Is that not what you wanted? I repeat, what are you
trying to do? What output do you want?

--
Nick Keighley- Hide quoted text -
Please edit out sig blocks like this.
I was expecting it to print 2007.But due to wrong byte swapping,it was
showing 55047 instead of 2007.
The idea behind asking this question is,I have got stream of data in
different data types and already an existing function recieves it and
parses it by bytes.I was trying to experiment with the structure and
see If I could extract it byte wise and get correct values.Incase I am
successful,I would go ahead and implement the same in our product.
This sounds like you have concluded that you should not use this
method, but you are 100% right. In most cases, a program that is to
read and interpret some external, binary, data format should read it
in bytes and put these together using shifts (or arithmetic). The
format of the data usually dictates which numbered byte is the least
significant and you use this to determine how to put the value back
together.

The "other" way -- where the program just takes the data an "overlays"
it onto an in-memory object is not portable. It can even break
between compiler releases if structure padding is changed, for
example. I wanted to assure you that you have probably got it right,
despite getting the wrong answer!

--
Ben.
Aug 12 '08 #6
Bart <bc@freeuk.comwrites:
On Aug 12, 9:44*am, ssubbarayan <ssu...@gmail.comwrote:
[...]
>I was expecting it to print 2007.But due to wrong byte swapping,it was
showing 55047 instead of 2007.
The idea behind asking this question is,I have got stream of data in
different data types and already an existing function recieves it and
parses it by bytes.

In this particular case you might know the year must be, say, 1900 to
2100. Any byte swapping will give year values outside this range
(except for year 2056 which is unaffected). In that case just reverse
the two bytes when the year is not already 1900 to 2100.
Sure, that will work in this particular case, but it's not a great
technique in general. Tomorrow you might have to handle data values
that are still plausible after being byte-swapped.

A more general approach is either to know in advance what the byte
ordering of the input file happens to be, or, if that's not feasible,
to have something in the file with a known value that will
unambigously tell you the byte ordering.

For example, a file might contain fixed fields containing the values
0x0102 (16 bits) and 0x01020304 (32 bits). Examining the values of
those fields should tell you what adjustments you need to perform for
other 16-bit and 32-bit fields.

Note that there are byte orderings others than big-endian and
little-endian. For a 32-bit value, 0x02010403 is a possibility on
some systems (but not on any systems you're particularly likely to
encounter).

For reasonable portability, the only values you probably need to worry
about are (0x0102, 0x01020304) and (0x0201, 0x04030201), as long as
you treat any other values as an error.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 12 '08 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Arthur J. O'Dwyer | last post by:
Well, I'm trying to write that program that was requested a few weeks back, the one that could take struct definitions and create portable functions to read and write those structs. Hence the...
4
by: Phui Hock | last post by:
Hi, I'm a newbie in C. Can anyone tell me why the size of 'test' is 8 bytes instead of 4 bytes when I uncomment the 'struct list *next;'? I hope someone can can explain to me. I can't find answer...
3
by: Aaron Walker | last post by:
At the beginning of my program, I open a config file and load the contents into a structure (please disregard the non-portable sockaddr_in struct as it is irrelevant to the problem): struct...
7
by: Capstar | last post by:
Hi NG, Does the following code invoke undefined behaviour? I compiled it and it runs fine. I think this is fine because I think the last 3 arguments of struct a are organised in memory the same...
8
by: Mike | last post by:
The following struct, DataStruct, is only part of a larger one that contains additional fields and arrays. I need the explicit layout because this struct is really a union, where some of the...
3
by: Dirk Reske | last post by:
Hello, I have the following struct: public struct WAVEFORMATEX { public UInt16 wFormatTag; //2 bytes public UInt16 nChannels; //2 bytes public UInt32 nSamplesPerSec; //4 bytes...
10
by: Giovanni Bajo | last post by:
Hello, given the ongoing work on struct (which I thought was a dead module), I was wondering if it would be possible to add an API to register custom parsing codes for struct. Whenever I use it...
5
by: Hallvard B Furuseth | last post by:
Does struct assignment copy padding bytes? Some compilers do, but I couldn't find anything in the standard which says they must. What I need is for any padding bytes to contan initialized values...
3
by: toton | last post by:
Hi, I have some ascii files, which are having some formatted text. I want to read some section only from the total file. For that what I am doing is indexing the sections (denoted by .START in...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.