Преобразование двоичной функции чтения из C # в C - PullRequest
2 голосов
/ 19 апреля 2011

Я, честно говоря, очень запутался при чтении бинарных файлов в C.

Мои данные в формате, подобном:

  • int header
  • Cell [] [] ячейки, матрица 8x8
  • Каждая ячейка - это просто короткий идентификатор и 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.

Ответы [ 4 ]

1 голос
/ 19 апреля 2011

Это вполне может быть связано с тем, что не всегда гарантируется, что короткое замыкание составляет два байта.Может быть, лучше прочитать указанное количество байтов, а затем преобразовать его в нужный тип данных?это также относится к Int.Кстати: fread возвращает количество прочитанных байтов, так что вы можете проверить, действительно ли прочитано нужное количество байтов.

С уважением, Перри

1 голос
/ 19 апреля 2011

Полагаю, вы можете использовать C # для записи файла (BinaryWriter) и C для его чтения.Таким образом, файл может иметь неожиданное значение в начале (некоторый заголовок, длина, спецификация и т. Д.).Используйте шестнадцатеричный редактор, чтобы быть уверенным.

1 голос
/ 19 апреля 2011

Вы должны использовать более строго определенные типы в C. Например, int32_t (stdint.h).Возможно, ваш short является 32-разрядным (или даже int 16-разрядным), хотя и маловероятно.

Возможно, также стоит показать нам, как определяется блок struct.

Для справки:

SByte = int8_t

Int16 = int16_t

Int32 = int32_t

0 голосов
/ 19 апреля 2011

В C переменные по умолчанию инициализируются в неопределенное состояние, поэтому вы не можете полагаться на их содержимое, пока не явным образом инициализируете их. Не забудьте выделить всю память, которая вам понадобится, и обнулить содержимое (инициализируя его), прежде чем они будут использованы.

Например: memset(&block, '\0', sizeof block);

...