tags:

views:

1685

answers:

7

Everything I'm finding via google is garbage... Note that I want the answer in C, however if you supplement your answer with a C++ solution as well then you get bonus points!

I just want to be able to read some floats into an array from a binary file

EDIT: Yes I know about Endian-ness... and no I don't care how it was stored.

+3  A: 

You could use fread. (Note the the API is for C, even though the website says C++ reference :))

Aviator
Bear in mind that depending on whether the float was written by a machine with different endian-ness then you may have to reorder the bytes after reading.
Jherico
I never know that :). thanks a lot!!
Aviator
+5  A: 
float f;
if(read(fd,&f,sizeof(f))==sizeof(f))
    printf("%f\n",f);
else
    printf("oops\n");

Provided that it's written as compatible binary representation.

read for file descriptors, fread for FILE*s and istream::read for c++ iostreams. Pick whatever pleases you:

read(fd,&f,sizeof(f))==sizeof(f)

fread(&f,sizeof(f),1,fp)==1

fin.read((char*)&f,sizeof(f)).gcount()==sizeof(f)
Michael Krelin - hacker
+10  A: 

How you have to read the floats from the file completely depends on how the values were saved there in the first place. One common way could be:

void writefloat(float v, FILE *f) {
  fwrite((void*)(&v), sizeof(v), 1, f);
}

float readfloat(FILE *f) {
  float v;
  fread((void*)(&v), sizeof(v), 1, f);
  return v;
}
sth
Thank you, I don't know why the hell it was so hard for everyone else I was finding on google to write that simple statement. I swear to God people just like making things more complicated for the hell of it.
Polaris878
Mind that the byte order does matter here if you move the file across platforms.
xtofl
I believe anything x86 or x64 will have the same endianness... correct?
Polaris878
What would I have to do if I wanted to read a fixed number of floats from th file? Thanks
Polaris878
@Polaris878: Call that function a fixed number of times?
sth
@Polaris878: just use `fread()` without the wrapper function (see my answer http://stackoverflow.com/questions/1422817/how-to-read-a-float-from-binary-file-in-c/1422869#1422869 ) - the sole reason for existence of this function with distinct parameters for object size and object count is to allow bulk reading
Christoph
It was so hard, because it was so obvious I imagine that most people must have assumed that you must have been having problems *exactly* because of all the gotcha's they were warning about. They were trying to help, and your question started out petulant; I don't know why they bothered. After all you only asked about reading; if your code wrote the file, you'd surely have known how to read it back? The solution given only works if the values are read and written by the same architcture. And it is not only an endian'ness issue, it is size and encoding as well.
Clifford
@ Clifford, yes I know it might seem obvious... however I was writing my file using the .NET libraries and had to read it in C from another process. I'm not familiar with many of the old school C APIs... Sorry I should've made that clear.
Polaris878
+1  A: 
FILE *thisFile=fopen("filename","fb");
float myFloat;
fscanf(thisFile,"%f",&myFloat);
fclose(thisFile);

This works if the data is written using fprintf (implementation specific)
However, you can also typecast your float to int32 and save , load and typecast.

std::fstream thisFile;
thisFile.open("filename",ios::read|ios::binary);
float myFloat;
thisFile>>myFloat;
thisFile.close();

May be wrong (I haven't used the C++ F.IO functions for a loooong loooong time)

Aviral Dasgupta
A: 

If these values are sequentially placed into a binary file you can do a read of sizeof(float) bytes per float value into a character array. You can then cast these into a float value.

Chaoz
+1  A: 

Use fread() from <stdio.h>. The assertions should be replaced with actual error handling code.

#include <stdio.h>
#include <assert.h>

#define countof(ARRAY) (sizeof (ARRAY) / sizeof *(ARRAY))

float data[5];

FILE *file = fopen("foo.bin", "rb");
assert(file);

size_t n = fread(data, sizeof(float), countof(data), file);
assert(n == countof(data));

Keep in mind that you might run into endian issues if you transfer files between different architectures.

Christoph
+1  A: 

If the file is all "float" and you wanted to read it X number of times, all you have to do is this:

FILE *fp;

if((fp=fopen("filename.whatever", "rb"))==NULL)
 return 0;

fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, 0, SEEK_SET);

float *f = (float *)malloc(sizeof(float)*size);
if(f==NULL)
{
 fclose(fp);
 return 0;
}

if(fread(f, sizeof(float), size, fp)!=size)
{
 fclose(fp);
 return 0;
}

fclose(fp);

// do something with f
Daniel