如何“读取"二进制文件 [英] How to "fread" a binary file

查看:104
本文介绍了如何“读取"二进制文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在当前路径中有一个二进制文件a.txt,其内容为:

3600字节-跟踪标头
数据块-每个块有400个数据

数据的类型为浮动".

我的问题是:如何读取数据块?

例如,我想读取第一个和第二个块中的数据.我可以使用以下代码吗?

I have a binary file, a.txt, in the current path with:

3600 bytes - trace header
data blocks - each block has 400 datas

The data is of type "float".

My question is: how do I read the data blocks?

For example, I want to read the data in the first and also the second block. Can I use the following code?

...
float a[400][2];
...
FILE *fp;
fp=fopen("a.txt","r");
for(int i=0;i<2;i++)
{
  fseek=(fp,long(3600+i*400*4),0);
  for(int j=0;j<400;j++)
    fread(&a[j][i],4,400,fp);

}
...

推荐答案

如果您的文件实际上是二进制格式("a.txt"对于二进制文件来说确实是一个坏名字),那么您应该跳过标头,然后立即读取数据块.
If your file is actually in binary format ("a.txt" is really a bad name for a binary file), then you should skip the header and then read the data block at once.
float a[2][400];
FILE * fp = fopen("a.txt", "rb");
if (!fp)
{
  // handle error here
}
// skip header
if ( fseek(fp, 3600, SEEK_SET) )
{
  // handle error
} 
// read the first data block into the array 
if ( fread( &a[0][0], sizeof(float), 400, fp) != 400)
{
  // handle error
}
// if the second data block follows immediately, then you use
// the following statements. On the other hand, if there is
// first another header block, skip it before.
 
if ( fread( &a[1][0], sizeof(float), 400, fp) != 400)
{
  // handle error
}


-要读取2个块,请使用此数组float a[2][400];.
-要读取二进制数据,请在fopen()中使用二进制模式.
-使用sizeof()表示数组元素的数量和一个元素的大小.因此,当您更改数组的大小或使用其他类型时,切勿更改读取代码.
-因为C中的数组已经是指针,所以在fread()中不需要a[i]的&运算符. -当数据块按串行顺序排列时,在fread()调用之间不需要fseek().您甚至不需要循环,就可以在一个fread()调用中读取所有数据.
-long(3600+i*400*4)不是C类型转换.它是一个C ++复制构造函数.这可以在C ++编译器中进行编译,但是C类型转换被编写为(long)3600+i*400*4.
-做一些错误处理测试.

最终,它看起来可能像这样:
- When you want to read 2 blocks, use this array float a[2][400];.
- To read binary data, use binary mode in fopen().
- Use sizeof() for the number of array elements and size of one element. So when you change the size of the array or use another type you must not change the code for reading.
- Because an array in C is allready a pointer, you don''t need the &-operator for a[i] in fread().
- When the data blocks are in serial order, you don''t need a fseek() between the fread() calls. You even don''t need a loop, you could read all data within one fread() call.
- The long(3600+i*400*4) is not a C typecast. It is a C++ copy constructor. This would compile in a C++ compiler but a C typecast is written (long)3600+i*400*4.
- Do some tests for error handling.

Finaly, it could look like this:
float a[2][400];
FILE *fp = fopen( "a.txt","rb");
if( NULL != fp)
{
   size_t nElements = sizeof(a[0]) / sizeof(a[0][0]);
   for( int i=0; i<2; i++)
   {
      long lOffset = 3600 + i * sizeof(a[0]);
      if( 0 == fseek( fp, lOffset, SEEK_SET))
      {
         if( nElements != fread( a[i], sizeof(a[0][0]), nElements, fp))
         {
            // error handling
            break;
         }
      }
      else
      {
         // error handling
         break;
      }
   }
}


运行代码会发生什么?

我不是C程序员,但我的C快速参考指南告诉我您使用的fread函数不正确.

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

内循环中每次读取fread都将读取400个大小为4个字节(即1600个字节)的数据元素.我想你打算写
fread(&a[j][i],4,1,fp);

在包含fseek的行中也存在语法错误,您需要先更正此错误,然后才能成功编译代码.

艾伦.
What happens when you run the code?

I''m not a C programmer but my C Quick Reference guide tells me that you are using the fread function incorrectly.

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

Each invocation of fread in the inner loop is reading 400 data elements of size 4 bytes, i.e. 1600 bytes. I think you meant to write
fread(&a[j][i],4,1,fp);

There is also a syntax error in the line containing fseek which you''ll need to correct before you can compile the code successfully.

Alan.


这篇关于如何“读取"二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆