Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Read n bytes from file

Reply
Thread Tools

Read n bytes from file

 
 
Alexander Hunziker
Guest
Posts: n/a
 
      07-05-2005
Hello group,

I have a program that reads data from a binary file. I know that at some
known position in the file there are 12 4 bytes long floating point
numbers. Here's how I read them now:

float temptriangle[12];

fread(&temptriangle, 4, 12, fp);

This works quite nicely, however it does so only if sizeof(float) is 4,
otherwise I'll get garbage.

Is there a cleaner way of doing it? Reading 4 bytes from a file into a
floating point variable?

Thanks in advance for your help,
Alex

 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      07-05-2005
Alexander Hunziker wrote:

> Hello group,
>
> I have a program that reads data from a binary file. I know that at some
> known position in the file there are 12 4 bytes long floating point
> numbers. Here's how I read them now:
>
> float temptriangle[12];
>
> fread(&temptriangle, 4, 12, fp);
>
> This works quite nicely, however it does so only if sizeof(float) is 4,
> otherwise I'll get garbage.
>
> Is there a cleaner way of doing it? Reading 4 bytes from a file into a
> floating point variable?


"Cleanliness is next to Godliness and next to impossible,
too." You are aware, I hope, that different C implementations
use different binary representation for `float', so your binary
file may be meaningful only to the machine that wrote it. You
have already sacrificed a certain amount of cleanliness by
choosing to use a binary format.

That said, the code as written can be scrubbed to a somewhat
brighter gleam. First, get rid of the address-of `&' operator;
see Question 6.12 in the comp.lang.c Frequently Asked Questions
(FAQ) list <http://www.eskimo.com/~scs/C-faq/top.html> if you
don't understand why this is the right thing to do. Second,
you can rewrite the "magic numbers" `4' and `12' in terms of
the `sizeof' operator. This would give something like

fread(temptriangle, sizeof temptriangle[0],
sizeof temptriangle / sizeof temptriangle[0], fp);

(The third argument is correct only if `temptriangle' is an
actual array rather than a pointer; see Question 6.21 in the FAQ.)

Even this isn't quite as clean as it should be, because it
lacks one important feature: it doesn't check whether fread()
succeeded or failed. You really need something more like

if (fread(temptriangle, ...)
!= sizeof temptriangle / sizeof temptriangle[0])
complain_and_die();

See the Sixth Commandment at
<http://www.lysator.liu.se/c/ten-commandments.html>.

--
Eric Sosman
lid
 
Reply With Quote
 
 
 
 
Gordon Burditt
Guest
Posts: n/a
 
      07-05-2005
>> I have a program that reads data from a binary file. I know that at some
>> known position in the file there are 12 4 bytes long floating point
>> numbers. Here's how I read them now:

>
>Second,
>you can rewrite the "magic numbers" `4' and `12' in terms of
>the `sizeof' operator.


I'll disagree here. The file format spec said it had floating point
numbers that are *FOUR* bytes long. This is independent of the
sizeof(float) on the target machine.

The file format spec also said there were *TWELVE* numbers, not
the number in any particular array. It is quite possible that
someone might re-use the array later for a set of 17 numbers.

Gordon L. Burditt
 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      07-06-2005
On Tue, 05 Jul 2005 21:27:10 +0200, Alexander Hunziker wrote:

> Hello group,
>
> I have a program that reads data from a binary file. I know that at some
> known position in the file there are 12 4 bytes long floating point
> numbers. Here's how I read them now:
>
> float temptriangle[12];
>
> fread(&temptriangle, 4, 12, fp);
>
> This works quite nicely, however it does so only if sizeof(float) is 4,
> otherwise I'll get garbage.


The question is whether you know that the format of the floating point
values in the file corresponds to the representation used by float on your
implementation. If it does then fine if it doesn't then clearly this won't
work. And of sizeof(float) is not 4 then clearly the format/representation
differs. It could differ even if sizeof(float)==4.

> Is there a cleaner way of doing it? Reading 4 bytes from a file into a
> floating point variable?


To make the code general you would have to interpret the bit pattern of
each float in the file data and build values from that.

Lawrence
 
Reply With Quote
 
Giorgos Keramidas
Guest
Posts: n/a
 
      07-06-2005
(Gordon Burditt) writes:
>>> I have a program that reads data from a binary file. I know that at some
>>> known position in the file there are 12 4 bytes long floating point
>>> numbers. Here's how I read them now:

>>
>> Second,
>> you can rewrite the "magic numbers" `4' and `12' in terms of
>> the `sizeof' operator.

>
> I'll disagree here. The file format spec said it had floating point
> numbers that are *FOUR* bytes long. This is independent of the
> sizeof(float) on the target machine.
>
> The file format spec also said there were *TWELVE* numbers, not
> the number in any particular array. It is quite possible that
> someone might re-use the array later for a set of 17 numbers.


Even so, "magic" constants are evil. Use #define and a nice block of
comments to describe their "magic" values.

- Giorgos

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      07-06-2005
Gordon Burditt wrote:
>>>I have a program that reads data from a binary file. I know that at some
>>>known position in the file there are 12 4 bytes long floating point
>>>numbers. Here's how I read them now:

>>
>>Second,
>>you can rewrite the "magic numbers" `4' and `12' in terms of
>>the `sizeof' operator.

>
>
> I'll disagree here. The file format spec said it had floating point
> numbers that are *FOUR* bytes long. This is independent of the
> sizeof(float) on the target machine.


That's a possible interpretation. I read the O.P. a bit
differently, believing that when he wrote "4" he meant "the
size of the local `float'." The example code (which you
snipped) suggests that the file holds images of the local
`float' and not some independently-specified format. If the
file format *isn't* native, a lot more work is needed.

> The file format spec also said there were *TWELVE* numbers, not
> the number in any particular array. It is quite possible that
> someone might re-use the array later for a set of 17 numbers.


Yes; it's possible that "12" is non-magical. It is, after
all, a peculiar number of values with which to describe a triangle.
(One might even say it's an "odd" number of values . Three
points with four values each -- X,Y,Z,T? X,Y,dX/dT,dY/dT?

--
Eric Sosman
lid
 
Reply With Quote
 
Malcolm
Guest
Posts: n/a
 
      07-06-2005

"Alexander Hunziker" <> wrote
> float temptriangle[12];
>
> fread(&temptriangle, 4, 12, fp);
>
> This works quite nicely, however it does so only if sizeof(float) is 4,
> otherwise I'll get garbage.
>
> Is there a cleaner way of doing it? Reading 4 bytes from a file into a
> floating point variable?
>


Reconstruct the floating point number from binary.

/*
portable read of binary float.
Note untested guide code to show the principle only. Your exact floating
point format may differ. */
*/
float readfloat(FILE *fp)
{
unsigned char byte1;
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
int sign;
int exponent;
int mantissa;
double answer;

byte0 = fgetc(fp);
byte1 = fgetc(fp);
byte2 = fgetc(fp);
byte3 = fgetc(fp);

sign = byte0 & 0x80 ? 1 : 0;
exponent = ((byte0 & 0x7F) << 1) + ((byte1 & 0x80) >> 7);
mantissa = ((byte1&0x7F) << 16) + (byte2 << + byte3;

if(exponent == 0 || exponent == 0xFF)
{
/* these are denormalised numbers, nans, and other horrible things
handle specially or reject. Zero you are likely to need */
if( byte0 == 0 && byte1 == 0 && byte2 == 0 && byte3 == 0)
return 0;
}
exponent -= 0x80;
/* reconstruct the floating point number. It is in the form (1 + mantissa)
* 2 ^ exponent */
answer = (((double)mantissa) / 0x800000 + 1.0) * pow(2, exponent);

if(sign)
answer = -answer;

return (float) answer;

}


 
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
When using System.IO.FileStream, I write 8 bytes, then seek to the start of the file, does the 8 bytes get flushed on seek and the buffer become a readbuffer at that point instead of being a write buffer? DR ASP .Net 2 07-29-2008 09:50 AM
When using System.IO.FileStream, I write 8 bytes, then seek to the start of the file, does the 8 bytes get flushed on seek and the buffer become a readbuffer at that point instead of being a write buffer? DR ASP .Net Building Controls 0 07-29-2008 01:37 AM
Ratio of Bytes Delayed to Bytes Sent netproj Cisco 0 12-21-2005 08:08 PM
Why file containing 256 bytes is 257 bytes long? Yandos C++ 12 09-14-2005 11:53 PM
Private Bytes vs. # Bytes in all Heaps in Perfmon Jason Collins ASP .Net 3 02-18-2004 03:59 PM



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