473,547 Members | 2,638 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

fwrite, fgets binary file readback problem

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[BITE_RECORD_LEN];
struct {
unsigned char type; /* 0 Type */
unsigned char sn[3]; /* 1-3 Serial Number */
unsigned char date_yy; /* 4 Date - Year */
unsigned char date_mm; /* 5 Date - Month */
unsigned char date_dd; /* 6 Date - Day */
unsigned char flight_leg; /* 7 Number */
unsigned char time_hh; /* 8 Time of Day - Hours */
unsigned char time_mm; /* 9 Time of Day - Minutes
*/
unsigned char etime[2]; /* 10-11 Elapsed Time */

struct { /* 12 Corrective Action
Status */
unsigned char spare: 6; /* bits 5-0, Spare */
unsigned char maint_alert: 1; /* bit 6, Alert,
1 = alert */
unsigned char serviced: 1; /* bit 7, Status,
1 = fault serviced */
} caa_status;
} field;
} myrecord;

I open it with: (some details ommitted)

fp = fopen(filename, "wb");

I write it as:

myrecord temp_fault_reco rd;
fwrite(.byte, BITE_RECORD_LEN , 1, fp);

my call to ReadFile:
fopen(file, "rb");

m_fault_record = (myrecord *) malloc (size);
int num = ReadFile (file_des, (unsigned char *)m_fault_recor d,
size);

I read it back via fgets:

int ReadFile(FILE *fp, unsigned char *buf, int count)
{
if (fgets((char *)buf, count, fp) == NULL)
{
debug_message(" ERROR ReadFile reading data");
return -1;
}
return count;
}

My problem is that after about 6 records (I loop over the
'm_fault_record ')
my data is not valid. 'size' above is calculated by stat'ing the file
being read
and is correct.

At this point Ive spent several hours parsing down the code to a small
executable and trying to find the problem with no luck, which is why
Im posting
this here to ask. Ive looked at google for a while too for fgets. I
saw some people
talking about fread() for binary files, but it seemed more for
efficiency than a need
in my case.

If Ive missed any details please just reply and Ill add them. I think
I got everything.
I appreciate any and all comments. Someone else may see what Im doing
wrong.

As a sidenote, Im porting this code from c to c++ (which shouldnt be a
problem).
The old code used CVI/Labview for the ReadFile call, which I dont have
and I just
ported it to what I thought would be equivalent, and it should be
easy, but apparently
its not been.

Thanks,
Jeff
Jun 27 '08 #1
27 5072
In article <51************ *************** *******@a9g2000 prl.googlegroup s.com>,
Jeff <je**@rahul.net wrote:
>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[BITE_RECORD_LEN];
struct {
unsigned char type; /* 0 Type */
unsigned char sn[3]; /* 1-3 Serial Number */
unsigned char date_yy; /* 4 Date - Year */
unsigned char date_mm; /* 5 Date - Month */
unsigned char date_dd; /* 6 Date - Day */
unsigned char flight_leg; /* 7 Number */
unsigned char time_hh; /* 8 Time of Day - Hours */
unsigned char time_mm; /* 9 Time of Day - Minutes
*/
unsigned char etime[2]; /* 10-11 Elapsed Time */

struct { /* 12 Corrective Action
Status */
unsigned char spare: 6; /* bits 5-0, Spare */
unsigned char maint_alert: 1; /* bit 6, Alert,
1 = alert */
unsigned char serviced: 1; /* bit 7, Status,
1 = fault serviced */
} caa_status;
} field;
} myrecord;
Check that sizeof myrecord.field is the same as BITE_RECORD_LEN
(and it wouldn't hurt to crosscheck that sizeof myrecord is BITE_RECORD_LEN )

Compilers are allowed to put unnamed padding between structure elements
for any purpose (though there are some restrictions on bitfield padding.)
I would not -expect- padding between consequative unsigned char, but
it is a possibility. In particular, I would be concerned that the
the caa_status struct might end up with padding before or after it.
I notice that you have used unsigned char bitfields. In C89/C90,
the base type for a bitfield must be a (possibly qualified)
int, signed int, or unsigned int. C99 adds _Bool to the allowed base
type list, along with "or some other implementation-defined type".
Thus the structure you show violates a Contraint unless you
are using C99 and your implementation defines char as an allowed base type.
The result *could* be that each of those unsigned char base types
in caa_status is silently converted to unsigned int, with caa_status
thus ending up as large as an int rather than "as large as a char"
that is implicit in your code. This is a concrete reason why your
field substructure might not be BITE_RECORD_LEN .
--
"It is surprising what a man can do when he has to, and how
little most men will do when they don't have to."
-- Walter Linn
Jun 27 '08 #2
Jeff <je**@rahul.net writes:
Im trying to figure out why I cant read back a binary file correctly.
[...]
if (fgets((char *)buf, count, fp) == NULL)
fgets is not appropriate for reading binary data. Use fread.
--
char a[]="\n .CJacehknorstu" ;int putchar(int);in t main(void){unsi gned long b[]
={0x67dffdff,0x 9aa9aa6a,0xa77f fda9,0x7da6aa6a ,0xa67f6aaa,0xa a9aa9f6,0x11f6} ,*p
=b,i=24;for(;p+ =!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)bre ak;else default:continu e;if(0)case 1:putchar(a[i&15]);break;}}}
Jun 27 '08 #3
On Jun 5, 12:42 pm, Ben Pfaff <b...@cs.stanfo rd.eduwrote:
>
fgetsis not appropriate for reading binary data. Use fread.
Yep, that fixed it. Thanks for all the info from both of you!
Jeff
Jun 27 '08 #4
Ben Pfaff wrote:
Jeff <je**@rahul.net writes:
Im trying to figure out why I cant read back a binary file correctly.
...
if (fgets((char *)buf, count, fp) == NULL)

fgets is not appropriate for reading binary data.
To be more precise, it's not appropriate for reading binary data that
contains zero bytes. Since it doesn't return a length of characters
read, there is no way to distinguish between a read null byte and
the null byte with which it terminates the buffer (unless it's the
last
character in the buffer.)

It will also stop reading if it encounteres a '\n', which is often
desired with text streams, but not so much with binary streams.

The fact that fgets doesn't cope with null bytes in streams is often
a good reason to ignore it for parsing text streams in programs
that need an extra level of robustness.

--
Peter
Jun 27 '08 #5
Peter Nilsson wrote:
Ben Pfaff wrote:
>Jeff <je**@rahul.net writes:
>>Im trying to figure out why I cant read back a binary file correctly.
...
if (fgets((char *)buf, count, fp) == NULL)
fgets is not appropriate for reading binary data.

To be more precise, it's not appropriate for reading binary data that
contains zero bytes. Since it doesn't return a length of characters
read, there is no way to distinguish between a read null byte and
the null byte with which it terminates the buffer (unless it's the
last
character in the buffer.)

It will also stop reading if it encounteres a '\n', which is often
desired with text streams, but not so much with binary streams.

The fact that fgets doesn't cope with null bytes in streams is often
a good reason to ignore it for parsing text streams in programs
that need an extra level of robustness.
I agree with Ben that fgets() is inappropriate for reading binary files.
It is designed to read lines of text and present the line to the program
as a string. There is no general case for a null byte in a text stream.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jun 27 '08 #6
Peter Nilsson wrote:
Ben Pfaff wrote:
>Jeff <je**@rahul.net writes:
>>Im trying to figure out why I cant read back a binary file correctly.
...
if (fgets((char *)buf, count, fp) == NULL)

fgets is not appropriate for reading binary data.

To be more precise, it's not appropriate for reading binary data that
contains zero bytes. Since it doesn't return a length of characters
read, there is no way to distinguish between a read null byte and
the null byte with which it terminates the buffer (unless it's the
last character in the buffer.)

It will also stop reading if it encounteres a '\n', which is often
desired with text streams, but not so much with binary streams.

The fact that fgets doesn't cope with null bytes in streams is often
a good reason to ignore it for parsing text streams in programs
that need an extra level of robustness.
However there is no restriction against using getc (or fgetc),
which will convert the '\n's from text files correctly, and pass
all the zero bytes. This makes the code depend only on the actual
file type. getc, if macro implemented, will be just as fast, and
eliminates the need for a buffer array.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #7
CBFalconer <cb********@yah oo.comwrites:
However there is no restriction against using getc (or fgetc),
which will convert the '\n's from text files correctly,
getc will not do any conversion on new-line characters in files
opened in binary mode, on the implementations with which I am
familiar.
and pass all the zero bytes. This makes the code depend only
on the actual file type. getc, if macro implemented, will be
just as fast, and eliminates the need for a buffer array.
On the implementations with which I am familiar, a sequence of
getc calls will not be as fast as a single fread or fgets call
that reads the same number of bytes. This is because every call
to getc must check whether the end of the file buffer has been
reached, but fread or fgets typically only needs to check for the
end of the buffer once.
--
char a[]="\n .CJacehknorstu" ;int putchar(int);in t main(void){unsi gned long b[]
={0x67dffdff,0x 9aa9aa6a,0xa77f fda9,0x7da6aa6a ,0xa67f6aaa,0xa a9aa9f6,0x11f6} ,*p
=b,i=24;for(;p+ =!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)bre ak;else default:continu e;if(0)case 1:putchar(a[i&15]);break;}}}
Jun 27 '08 #8
Ben Pfaff wrote:
CBFalconer <cb********@yah oo.comwrites:
>However there is no restriction against using getc (or fgetc),
which will convert the '\n's from text files correctly,

getc will not do any conversion on new-line characters in files
opened in binary mode, on the implementations with which I am
familiar.
That's what I thought I said. :-)
>
>and pass all the zero bytes. This makes the code depend only
on the actual file type. getc, if macro implemented, will be
just as fast, and eliminates the need for a buffer array.

On the implementations with which I am familiar, a sequence of
getc calls will not be as fast as a single fread or fgets call
that reads the same number of bytes. This is because every call
to getc must check whether the end of the file buffer has been
reached, but fread or fgets typically only needs to check for the
end of the buffer once.
However, it will be close. At any rate, such differences will be
lost in the actual hardware access times.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #9
In article <48************ ***@yahoo.com>,
CBFalconer <cb********@mai neline.netwrote :
>However there is no restriction against using getc (or fgetc),
which will convert the '\n's from text files correctly, and pass
all the zero bytes.
All the stdio functions will convert line ends in text mode, and not
in binary mode. There's no difference between getc(), fgets(), and
fread() in this respect.

-- Richard
--
In the selection of the two characters immediately succeeding the numeral 9,
consideration shall be given to their replacement by the graphics 10 and 11 to
facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)
Jun 27 '08 #10

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

Similar topics

14
3739
by: Kevin Knorpp | last post by:
Hello. I need to be able to extract the data from the attached file (or any file in the same format) so that I can work with the data in PHP. I'm fairly comfortable with using PHP with databases, arrays, etc. but have not worked with binary data files. http://www.performancecentral.net/C...3Loop/3Loop.php click on "Download...
3
4089
by: sredd01 | last post by:
Hello, Please look the code below where I am reading the first 2,2,4 bytes from a binary file using two methods. I am getting a wierd (wrong) output with ifstream and memcpy method, but get the correct output with CFile read. I am trying to get the values 1400 1050 and 2014 from the binary file. Can anybody point out the mistake in the...
3
2716
by: Joshua Russell | last post by:
Hi, I've got a program (see source below) that makes a file and fills it with random binary values (from 0 to 255). The source below works, however the program creates files at a rate of about 0.5MB per second. There is a serious performance issue with this program. There is a loop within the main loop that generates a buffer of 500 Bytes...
10
4141
dmjpro
by: dmjpro | last post by:
is it the right way to read the content of a .jpg or .jif using Reader subclasses.... my code is something like this ....... FileReader l_file = new FileReader("file_name"); String line = null; while((line = l_file.readLine()) != -1) {
0
7510
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7703
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7947
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
6032
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5362
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5081
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3493
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3473
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1923
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.