将二进制读取函数从 C# 转换为 C

发布于 2024-11-02 08:07:54 字数 1345 浏览 3 评论 0原文

老实说,我对读取 C 中的二进制文件感到非常困惑。

我的数据格式如下:

  • int header
  • Cell[][] cells, 8x8 矩阵
  • 每个单元格只是一个短 id 和一个 sbyte z。

然而,显然有些事情出了问题,并且没有一个值是准确的。

  int i, j;
  Block block;

  // read 32 bits
  fread( &(block.header), sizeof( int ), 1, mapFile );

  // loop through to fill the 8x8 matrix
  for( i = 0; i < 8; i++ )
  {
    for( j = 0; j < 8; j++ )
    {
      // read 16 bits
      fread( &(block.cells[i][j].tileId), sizeof( short ), 1, mapFile );
      // read 8 bits
      fread( &(block.cells[i][j].z), sizeof( char ), 1, mapFile );

      printf( "[%i][%i]: %x %i", i, j, block.cells[i][j].tileId, block.cells[i][j].z );
    }
  }
  printf( "header: %i", block.header );

上面的输出显示了一堆带有 [n][n]: ffffa800 251 的行。

不过,我的 C# 版本工作正常:

            Block block;
            block.header = reader.ReadInt32();
            block.cells = new Cell[8,8];
            for( int i = 0; i < 8; i++ )
            {
                for ( int j = 0; j < 8; j++ )
                {
                    block.cells[i, j].tileId = reader.ReadInt16();
                    block.cells[i, j].z = reader.ReadSByte();
                }
            }

            reader.Close();

输出(正确)显示 [n][n]: a8 -5

I am honestly really confused on reading binary files in C.

My data is in a format like:

  • int header
  • Cell[][] cells, 8x8 matrix
  • Each cell is just a short id and a sbyte z.

However, something is clearly messing up and none of the values are accurate.

  int i, j;
  Block block;

  // read 32 bits
  fread( &(block.header), sizeof( int ), 1, mapFile );

  // loop through to fill the 8x8 matrix
  for( i = 0; i < 8; i++ )
  {
    for( j = 0; j < 8; j++ )
    {
      // read 16 bits
      fread( &(block.cells[i][j].tileId), sizeof( short ), 1, mapFile );
      // read 8 bits
      fread( &(block.cells[i][j].z), sizeof( char ), 1, mapFile );

      printf( "[%i][%i]: %x %i", i, j, block.cells[i][j].tileId, block.cells[i][j].z );
    }
  }
  printf( "header: %i", block.header );

Output of above shows a bunch of lines with [n][n]: ffffa800 251.

My C# version works fine though:

            Block block;
            block.header = reader.ReadInt32();
            block.cells = new Cell[8,8];
            for( int i = 0; i < 8; i++ )
            {
                for ( int j = 0; j < 8; j++ )
                {
                    block.cells[i, j].tileId = reader.ReadInt16();
                    block.cells[i, j].z = reader.ReadSByte();
                }
            }

            reader.Close();

Output from that (correctly) shows [n][n]: a8 -5.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沉鱼一梦 2024-11-09 08:07:54

您应该在 C 中使用更严格定义的类型。例如,int32_t (stdint.h)。您的 short 可能是 32 位(甚至您的 int 是 16 位),尽管可能性不大。

向我们展示 Block struct 是如何定义的可能也是值得的。

供参考:

SByte = int8_t

Int16 = int16_t

Int32 = int32_t

You should use more strictly defined types in C. For example, int32_t (stdint.h). It's possible that your short is 32-bit (or even your int is 16-bit), albeit unlikely.

It's probably also worthwhile to show us how the Block struct is defined.

For reference:

SByte = int8_t

Int16 = int16_t

Int32 = int32_t

灯角 2024-11-09 08:07:54

这很可能与以下事实有关:short 并不总是保证为两个字节。也许最好读取指定数量的字节,然后将其转换为所需的数据类型?这也适用于 int。顺便说一句:fread 返回读取的字节数,因此您可以检查是否实际读取了所需的字节数。

问候,佩里

This might very well have to do with the fact that a short is not always guaranteed to be two bytes. Maybe it is better to read the specified number of bytes and then convert it into the desired datatype? this also goes for int. By the way: fread returns the number of bytes read, so you are able to check if the desired number of bytes is actually read.

Regards, Perry

狼亦尘 2024-11-09 08:07:54

我相信您可能正在使用 C# 来写入文件 (BinaryWriter) 并使用 C 来读回它。因此,文件在开始时可能有一些意想不到的值(一些标头、长度、BOM 等)。使用十六进制编辑器来确定。

I believe you may be using C# to write the file (BinaryWriter) and C to read it back. Thus the file may have some unexpected value at the beginning (some header, length, a BOM whatever). Use a hex editor to be sure.

娇纵 2024-11-09 08:07:54

在 C 中,变量默认初始化为未定义状态,因此在显式初始化它们之前,您不能依赖它们的内容。请记住分配您需要的所有内存,并在使用内容之前将其清零(初始化它们)。

例如:memset(&block, '\0', sizeof block);

In C variables are initialized by default to an undefined state, so you cannot rely on their contents until you have explicitly initialized them. Remember to allocate all the memory that you will need and to zero out the contents (initializing them) before they are used.

For example: memset(&block, '\0', sizeof block);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文