473,386 Members | 1,973 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,386 software developers and data experts.

Binary files, structs and fread

Hey,

I'm working on a program that reads a binary file. It's opened with
====
if ((f1=fopen(argv[1],"rb"))==NULL) {
fprintf(stderr,"Error opening %s for reading . . .\n",argv[1]);
exit(2);
}
====
The structure of the file is:

unsigned int
unsigned short
unsigned short
unsigned short
unsigned short
unsigned short
<more data>
{eof}
I have a structure:

typedef struct struct_fileinfo {
unsigned int num;
unsigned short ins;
unsigned short del;
unsigned short nex;
unsigned short est;
unsigned short get;
} FILEINFO;

int main(int argc, char** argv) {
FILEINFO data;
FILE* f1;
[......]

I use:
if ((fread(&data,sizeof(FILEINFO),1,f1))!= 1) {
fprintf(stderr,"\n\t\tError reading into fileinfo\n\n");
exit(3);
}
to read a chunk the size of FILEINFO.

When I go to output the data read with

fprintf(stdout,"%hd",data.num);

I dont get a value I'm expecting. Am I using the proper printf
identifier (%hd for unsigned int and %hu for unsigned short)? Should i
be casting the values before output? Any suggestions? OS is Solris 8
on Enterprise 220R.

Thanks!
Luc
Nov 13 '05 #1
2 15547


Luc Holland wrote:
Hey,

I'm working on a program that reads a binary file. It's opened with
====
if ((f1=fopen(argv[1],"rb"))==NULL) {
fprintf(stderr,"Error opening %s for reading . . .\n",argv[1]);
exit(2);
}
====
The structure of the file is:

unsigned int
unsigned short
unsigned short
unsigned short
unsigned short
unsigned short
<more data>
{eof}
I have a structure:

typedef struct struct_fileinfo {
unsigned int num;
unsigned short ins;
unsigned short del;
unsigned short nex;
unsigned short est;
unsigned short get;
} FILEINFO;

int main(int argc, char** argv) {
FILEINFO data;
FILE* f1;
[......]

I use:
if ((fread(&data,sizeof(FILEINFO),1,f1))!= 1) {
fprintf(stderr,"\n\t\tError reading into fileinfo\n\n");
exit(3);
}
to read a chunk the size of FILEINFO.

When I go to output the data read with

fprintf(stdout,"%hd",data.num);
data.num is type unsigned int. The specifier should be %u.
I dont get a value I'm expecting. Am I using the proper printf
identifier (%hd for unsigned int and %hu for unsigned short)? Should i
be casting the values before output? Any suggestions? OS is Solris 8
on Enterprise 220R.


You need to be aware that the sizeof the individual struct members may
not equate to the sizeof the struct. The struct may have padding
making it larger than the total members size. This would cause
an alignment problem with your code.
See the faq: http://www.eskimo.com/~scs/C-faq/q2.13.html

If you can't modify the data file, you could write a function
that will read the data file and store the data in a struct.

#include <stdio.h>
#include <stdlib.h>

/* data in data file
unsigned int
unsigned short
unsigned short
unsigned short
unsigned short
unsigned short
<more data>
{eof} */

typedef struct struct_fileinfo {
unsigned int num;
unsigned short ins;
unsigned short del;
unsigned short nex;
unsigned short est;
unsigned short get;
} FILEINFO;

int GetData(FILEINFO *p,const char *fname);

int main(void)
{
const char *fname = "test.dat";
unsigned short i;
unsigned int d = 99;
FILEINFO test = {0,0,0,0,0,0};
FILE *fp;

/* Create a test file */
if((fp = fopen(fname,"wb")) == NULL) exit(EXIT_FAILURE);
if(1 != fwrite(&d,sizeof(d),1,fp)) exit(EXIT_FAILURE);
for(i = 0; i < 5;i++)
if(1 != fwrite(&i,sizeof(i),1,fp)) exit(EXIT_FAILURE);
fclose(fp);

printf("The sizeof the indivual elements: %u\n",
sizeof(short)*5+sizeof(unsigned int));
printf("The sizeof of the struct is: %u\n",
sizeof(FILEINFO));

if(GetData(&test,fname))
printf("test.mum = %u\ntest.ins = %hd\n"
"test.del = %hd\ntest.nex = %hd\n"
"test.est = %hd\ntest.get = %hd\n",
test.num,test.ins,test.del,test.nex,
test.est,test.get);
return 0;
}

int GetData(FILEINFO *p,const char *fname)
{
FILE *fp;
int flag = 1;

if((fp = fopen(fname,"rb")) == NULL) return 0;
if(1 != fread(&p->num,sizeof(p->num),1,fp)) flag = 0;
if(1 != fread(&p->ins,sizeof(p->ins),1,fp)) flag = 0;
if(1 != fread(&p->del,sizeof(p->del),1,fp)) flag = 0;
if(1 != fread(&p->nex,sizeof(p->nex),1,fp)) flag = 0;
if(1 != fread(&p->est,sizeof(p->est),1,fp)) flag = 0;
if(1 != fread(&p->get,sizeof(p->get),1,fp)) flag = 0;
fclose(fp);
return flag;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa*@abowers.combase.com (remove the x)
http://www.geocities.com/abowers822/

Nov 13 '05 #2
On Sun, 20 Jul 2003 19:53:50 -0400, Al Bowers wrote:
You need to be aware that the sizeof the individual struct members may
not equate to the sizeof the struct. The struct may have padding making
it larger than the total members size. This would cause an alignment
problem with your code.
See the faq: http://www.eskimo.com/~scs/C-faq/q2.13.html

If you can't modify the data file, you could write a function that will
read the data file and store the data in a struct.
<snip> int GetData(FILEINFO *p,const char *fname) {
FILE *fp;
int flag = 1;

if((fp = fopen(fname,"rb")) == NULL) return 0; if(1 !=
fread(&p->num,sizeof(p->num),1,fp)) flag = 0; if(1 !=
fread(&p->ins,sizeof(p->ins),1,fp)) flag = 0; if(1 !=
fread(&p->del,sizeof(p->del),1,fp)) flag = 0; if(1 !=
fread(&p->nex,sizeof(p->nex),1,fp)) flag = 0; if(1 !=
fread(&p->est,sizeof(p->est),1,fp)) flag = 0; if(1 !=
fread(&p->get,sizeof(p->get),1,fp)) flag = 0; fclose(fp); return
flag;


There are two methods I advocate for reading and writing binary
formats. If the format does not need to be portable and it is generated
by your code or you know the code generating the format is just writing
the entire sizeof(struct foo) to the file then just read sizeof(struct
foo) into a 'struct foo' as well. But if fields have specific offsets
or if the file needs to be transported to another machine for decoding,
it is better to explicitly decode the format using endian-aware functions.
My encdec package provides the encoding/decoding primatives for complex
formats using the later technique:

http://www.ioplex.com/~miallen/encdec/

The tests/t3encdec.c test program illustrates how I would encode and
decode a struct like FILEINFO.

I do not advocate mixing the two techniques. If you're going to go
through the trouble of decoding each field, you might as well do it in
a portable way.

Mike
Nov 13 '05 #3

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

Similar topics

7
by: laclac01 | last post by:
So I am converting some matlab code to C++. I am stuck at one part of the code. The matlab code uses fread() to read in to a vector a file. It's a binary file. The vector is made up of floats,...
28
by: wwj | last post by:
void main() { char* p="Hello"; printf("%s",p); *p='w'; printf("%s",p); }
9
by: Arnold | last post by:
I need to read a binary file and store it into a buffer in memory (system has large amount of RAM, 2GB+) then pass it to a function. The function accepts input as 32 bit unsigned longs (DWORD). I...
2
by: anirudhvr | last post by:
Hi, I needed a basic binary to ascii encoder, so I wrote this piece of code: /* Encoding algo: suppose 11111010 is the byte to be encoded. It is first broken up into two 4-bit parts (1111...
2
by: underground | last post by:
I need a little help figuring this one out. I have a script that should post mutiple binary files into a single row but instead of copying the indiviuals files it rewrites the first file to all the...
10
by: underground | last post by:
I need a little help figuring this one out. I have a script that I've modified to post mutiple binary files into a single row but instead of copying the indiviuals files it rewrites the first file to...
7
by: Ludo | last post by:
Hi, I'm working on an open source project and I have a problem with a binary file. When I read the binary file with the program downloaded from sourceforge, I have no problem. However, I'm unable...
27
by: Jeff | last post by:
Im trying to figure out why I cant read back a binary file correctly. I have the following union: #define BITE_RECORD_LEN 12 typedef union { unsigned char byte; struct { unsigned char type;...
22
by: xiao | last post by:
Can I fullfill this task? Using fred and fwrite?
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

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.