如何在C语言中从二进制文件中读取浮点数?

7

我在谷歌上找到的所有内容都是垃圾...请注意,我想要用C写答案,但如果您能提供一个C++解决方案,那么您将获得额外的奖励分数!

我只想从二进制文件中读取一些浮点数到数组中

编辑:是的,我知道字节序的问题...但我不关心它是如何存储的。


1
这些浮点数以什么样的格式存储? - Éric Malenfant
6
这就是我为什么喜欢StackOverflow的原因... 我只需要等几分钟,就已经有5个比其他任何地方都好的答案了。 - Polaris878
你并不关心浮点数是如何存储的,但你需要有人告诉你如何从二进制文件中读取这么基础的内容吗? - Razzupaltuff
抱歉,我不会每个 C API 都背下来 -_- - Polaris878
7个回答

19

从文件中读取浮点数的方式完全取决于首次保存值的方式。一种常见的方式可能是:

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;
}

1
谢谢,我不知道为什么在谷歌上找到的其他人写这个简单语句都那么困难。我发誓有些人就是喜欢刻意把事情变得更复杂。 - Polaris878
2
请注意,如果您在不同平台之间移动文件,则字节顺序确实很重要。 - xtofl
我认为所有的x86或x64都具有相同的字节序,是吗? - Polaris878
4
@Polaris878:把那个函数调用固定次数吗? - sth
@Polaris878:只需使用fread()而不是包装函数(参见我的答案https://dev59.com/WUnSa4cB1Zd3GeqPNFlf#1422869)- 这个函数存在的唯一原因是为了使用不同参数的物体大小和物体计数来允许批量读取。 - Christoph
显示剩余3条评论

5
float f;
if(read(fd,&f,sizeof(f))==sizeof(f))
    printf("%f\n",f);
else
    printf("oops\n");

只要它以兼容的二进制表示形式编写即可。

read 用于文件描述符,fread 用于 FILE*istream::read 用于 c++ iostreams。选择你喜欢的:

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

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

fin.read((char*)&f,sizeof(f)).gcount()==sizeof(f)

3

使用<stdio.h>中的fread()函数。应将断言替换为实际的错误处理代码。

#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));

请记住,如果在不同的架构之间传输文件,可能会遇到字节序问题。


3
你可以使用fread。(请注意,该API是用于C语言的,即使网站上写着C++参考文档:)

4
请记住,根据浮点数是由不同字节序的机器编写的,您可能需要在读取后重新排序字节。 - Jherico

2
如果文件中全部是“浮点数”,而您想要读取它X次,您只需要按照以下方式操作:
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

1
FILE *thisFile=fopen("filename","fb");
float myFloat;
fscanf(thisFile,"%f",&myFloat);
fclose(thisFile);

如果数据是使用fprintf(实现特定)编写的,则此方法有效。
然而,您也可以将浮点数强制转换为int32并保存、加载和类型转换。

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

可能有误(我已经很久很久没有使用C++ F.IO函数了)

O.P. 要求以二进制格式提供文件。这将生成 Ascii 格式的文件,虽然易于阅读,但并非所要求的格式。抱歉。 - DragonLord

0
如果这些值按顺序放入二进制文件中,您可以每个浮点值读取sizeof(float)字节到字符数组中。然后,您可以将它们转换为浮点值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接