Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems reading binary files

Status
Not open for further replies.

logic4fun

Programmer
Apr 24, 2003
85
0
0
US
All,
I am trying to read binary files and i am experiencing premature end of file. I checked with feof() and it reaches end of file. But when i do a strings on the binary file i see more records after it said end of file. Can somebody provide me an insight on this.

thanks in advance
logic4fun

 
post your fopen/fread code. the fopen should have the "rb" options.
 
Here is the code

if((fp1 = fopen(fname,"rb")) == NULL) {
printf("error opening file %s \n",fname);
exit(1);
}

while(1) {
if(fread(fieldlen,(2 * sizeof(fieldlen[0])),1,fp1)<1){
if(feof(fp1)) break;
}

bytes_read += (2 * sizeof(int));

memset((char*)string,0,sizeof(string));
if(fread(string,(fieldlen[0]+fieldlen[1]),1,fp1)<1) {;
fflush(stdout);
if(feof(fp1)) break;
printf("ERROR \n");
}

printf("String is : %s,%d,%d \n",string,fieldlen[0],fieldlen[1]);

strncpy(string1, string+fieldlen[0],fieldlen[1]);
bytes_read += (fieldlen[0]+fieldlen[1]);

printf("String is : %s \n",string1);

}
fclose(fp1);


****************************
Input File:

^H^@^@^@,^@^@^@notused^@O3,8113141004,IV,124,50,1107801594,100,1,1
^@^H^@^@^@X^@^@^@notused^@E3,124,50,8113141004,1107801594,1107801595,2,63000023,1107801594,124,50,^B1,2,EventText^C
^@^H^@^@^@,^@^@^@notused^@O3,8113141004,IV,124,50,1107801594,200,2,2
^@^H^@^@^@o^@^@^@notused^@E3,124,50,8113141004,1107801594,1107801595,1,63000023,1107801594,124,50,^B1,2,This is the data; ANI=4027160503^C
^@^H^@^@^@X^@^@^@notused^@E3,124,50,8113141004,1107801594,1107801595,2,63000023,1107801594,124,50,^B1,2,EventText^C
^@^H^@^@^@

After it encounters the E3 records it bails out.

Does it have something to do that how the binary file is getting created.
 
Please use the [tt][ignore]
Code:
[/ignore][/tt]
tags when posting code.

Also, post something resembling complete code. Just some statements without any variable declarations makes it impossible to guess how you declared the variables, and hence judge whether your use is appropriate.

Ideally, we just want to be able to copy/paste a small complete program which demonstrates the problem.

Also, which operating system and compiler are you using.

If you're on linux (or have cygwin installed on your windows machine), then use this approach to paste bits of binary files in an unambiguous manner.
Code:
$ od -t x1z hello.c | head
0000000 23 69 6e 63 6c 75 64 65 3c 73 74 64 69 6f 2e 68  >#include<stdio.h<
0000020 3e 0a 0a 69 6e 74 20 6d 61 69 6e 28 29 7b 0a 20  >>..int main(){. <
0000040 20 20 20 63 68 61 72 20 73 74 72 69 6e 67 5b 33  >   char string[3<
0000060 30 5d 3b 0a 20 20 20 20 73 63 61 6e 66 28 22 25  >0];.    scanf("%<
0000100 5b 5e 5c 6e 5d 5c 6e 22 2c 73 74 72 69 6e 67 29  >[^\n]\n",string)<
0000120 3b 0a 20 20 20 20 70 72 69 6e 74 66 28 22 25 73  >;.    printf("%s<
0000140 22 2c 73 74 72 69 6e 67 29 3b 0a 20 20 20 20 72  >",string);.    r<
0000160 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a              >eturn 0;.}..<
0000174

--
 
Code:
// this is fine ***
if((fp1 = fopen(fname,"rb")) == NULL) {
printf("error opening file %s \n",fname);
exit(1);
}

// this reads thru your entire file
// is this what you want?
// are the 1st two bytes an integer of the length of record
// 2nd parm should be sizeof(int) which = 2
// recsize = atoi(fieldlen);   
// then use this for next read
while(1) {
if(fread(fieldlen,(2 * sizeof(fieldlen[0])),1,fp1)<1){
if(feof(fp1)) break;
}

int rc;
char fieldlen[128];
int reclength;
memset(fieldlen,0,sizeof(fieldlen));
rc = fread(fieldlen,sizeof(int),1,fp1);
if (rc<1) error
reclength = atoi(fieldlen);
 
On reading through the binary 'dump' you provided I can see a straightforward problem with the first line with its second string beginning with 'E3' - in fact, it occurs in every E3 line - you have two non-text characters in that string - ^B and ^C, or hex 02 and 03 respectively. You're sending this directly to printf and I remember at least one system which used to use those as printer control characters (on and off). Not printing the strings may help. Secondly, the binary you've given terminates in broken fashion; it ends in an incomplete line for the format you've described.

However, you're not clear on where this fails for you - the first E3 line or the last? If it's after the last, it's working correctly unless there's more to that binary file. If it's after the first, the above commentary may help.
 
Since the code is incomplete, it's hard to tell.

Since also simply copy/pasting a binary file to a web page is also likely to skip/change vital information, it's hard to tell from that as well.

--
 
First of all feof with binary files will not work.
for binary files u have to get the length and then loop until
u read those many bytes.

like
ulong file_len = length of file pointed by fin
while (i < file_len) {
read from file fin;
}
 
First of all feof with binary files will not work.

It's wrong statement, but fread's returned value handling in all snippets above was (slightly;) incorrect too.
In the snippet below all declarations are for example only:
Code:
typedef .... BTYPE;
#define BSZ ...
BTYPE buff[BSZ];
size_t rcnt;
size_t bcnt = BSZ;
...
rcnt = fread(buff,sizeof(BTYPE),bcnt,f);
if (rcnt < bcnt)
{
   if (feof(f))
      /* EOF condition */
...
   if (ferror(f))
      /* input error condition */
}
So we must save returned value because of it's the number of full items actually read.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top