Запись двумерного массива в двоичный файл на С (получение странных результатов) - PullRequest
0 голосов
/ 24 ноября 2018

Я использую этот код для записи файла:

FILE *f = fopen("out/solution.raw", "wb");
int i, j;
//SIZE = 512
for(i = 0; i < SIZE; i++)
{
    fwrite(matrix[i], 1, SIZE, f);
}   

fclose(f);

Проблема в том, что когда я открываю файл, он между цифрами 3 и 0, вот 2 скриншота, которые помогут вам понятьчто я имею в виду:

Вот что я должен получить:

This is what I should be getting:

И вот что я получаю:

My output

Как вы можете видеть, мой код правильно записывает каждое число, но между ними есть три 0, и я понятия не имею, почему.

Я также пробовал это:

fwrite(matrix[i], sizeof(matrix[i][0]), SIZE, f);

Но ни одна из них не работает, любая помощь будет принята с благодарностью.


моя матрица объявлена ​​как двумерный массив целых, поскольку мне нужно выполнить некоторые операции с этими числами:

matrix = (int**)malloc(SIZE * sizeof(int*));
for (i = 0; i < SIZE; i++)
{
    matrix [i] = (int*)malloc(SIZE * sizeof(int*));
}

Я попробовал ваше решение, но не могу назначить неподписанный символ для int, поэтому я попытался привести его и получаюэто предупреждение:

приведение от указателя к целому числу другого размера.

unsigned char to_write;
for(i = 0; i < SIZE; i++)
{
    to_write = (unsigned char)matrix[i];
    fwrite(&to_write, 1, 1, f);
}   

(использованный код)

После этого я получаю:

enter image description here

Кстати, мои данные не подписаны.

1 Ответ

0 голосов
/ 24 ноября 2018

matrix[i] - указатель на 32-разрядные целые числа.Даже если вы присваиваете значения, которые хранятся в 8 битах, это не «сжимает» данные при записи в двоичный поток (плюс вы, вероятно, не записываете 512 значений, а только 512/4 = 128 значений)

Ваша машина имеет младший порядок, поэтому сначала вы получаете LSB, а затем 3 нуля для каждого значения.

Поэтому измените тип matrix[i] с int32_t * на char * или unsigned char * в зависимости от того, что вам нужно, убедитесь, что ваши значения находятся в 8-битном диапазоне, и вы можете использовать fwrite, как вы планируете.

Если вы не можете изменить тип данных matrixиспользуйте цикл для преобразования значений

for(i = 0; i < SIZE; i++)
{
    uint8_t to_write = matrix[i];  // assign/truncate for 0/255 range
    fwrite(&to_write, 1, 1, f);
}   

, если ваши данные подписаны, вы должны использовать int8_t.Но в этом случае вы не сможете написать a0 как 160.

РЕДАКТИРОВАТЬ: ваше редактирование показывает реальный тип matrix.matrix[i] - указатель на данные, поэтому вам нужно использовать двойной цикл для его вывода, иначе вы копируете адрес массива, а не значение

for(i = 0; i < SIZE; i++)
{
   const int *row = matrix[i];
   for(j = 0; j < SIZE; j++)
   {
       uint8_t to_write = row[j];  // assign/truncate for 0/255 range
       fwrite(&to_write, 1, 1, f);
   }
}   
...