Работа с бинарными файлами в си. Не могу найти ошибку

Условие задачи:

На вход подаётся бинарный файл в следующем формате: первые два байта являются целым числом, которое не превышает 2000 и задаёт размер квадратной матрицы, затем следуют целочисленные 32х битные элементы матрицы. Все числа находятся в представлении big-endian. Требуется отыскать след матрицы и вывести его в бинарный файл в виде 64х битного целого числа в формате big-endian.


#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE *input = fopen("matrix.in", "rb");
    unsigned int size = 0;
    int count = 0;
    int tmp = 0;
    int trash;
    long int sum = 0;
    size = fgetc(input) << 8;
    size += fgetc(input);
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            if (count == j)
            {
                int x = 0;
                for (int k = 24; k >= 0; k -= 8)
                {
                    fread(&tmp, sizeof(int8_t), 1, input);
                    x += tmp << k;
                }
                sum += x;
                break;
            }
            else
                fread(&trash, sizeof(int32_t), 1, input);
        }
        count++;
    }
    FILE *output = fopen("trace.out", "wb");
    long int mask = 0xFF00000000000000;
    for (int i = 0; i < 8; i++)
    {
        long int check = mask & sum;
        fwrite(&check, sizeof(int8_t), 1, output);
        mask >>= 8;
    }
    fclose(input);
    fclose(output);
    return 0;
}

Никак не пойму, в чем тут ошибка(((


Ответы (1 шт):

Автор решения: AlexGlebe

След матрицы — это сумма элементов главной диагонали матрицы.

Читать массив надо полностью, или вручную делать смещение по файлу с помощью fseek. А вы просто останавливаете чтение строки не переходя на новый ряд матрицы.

        if (count == j) { // можно просто ( i == j )
            int x = 0;
            for (int k = 24; k >= 0; k -= 8) {
                fread(&tmp, sizeof(int8_t), 1, input);
                x += tmp << k;
            }
            sum += x;

            break; // останавливаться нельзя

        } else
            fread(&trash, sizeof(int32_t), 1, input);

исправляем :

        if (i == j) {
            int x = 0;
            for (int k = 24; k >= 0; k -= 8) {
                fread(&tmp, sizeof(int8_t), 1, input);
                x += tmp << k;
            }
            sum += x;
        } else
            fread(&trash, sizeof(int32_t), 1, input);

или для ускорения процесса перемещаем позицию чтения файла с помощью fseek относительно начала файла :

for (unsigned int i = 0; i < size; i++) {
  
  fseek ( input , 2 + i * size * 4 + i * 4 , SEEK_SET ) ;
  
  int x = 0;
  for (int k = 24; k >= 0; k -= 8) {
    fread(&tmp, sizeof(int8_t), 1, input);
    x += tmp << k;
  }
  sum += x;
}

или от текущей позиции на следующий ряд :

for (unsigned int i = 0; i < size; i++) {
  int x = 0;
  for (int k = 24; k >= 0; k -= 8) {
    fread(&tmp, sizeof(int8_t), 1, input);
    x += tmp << k;
  }
  sum += x;
  
  fseek ( input , size * 4 , SEEK_CUR ) ;
  
}    
→ Ссылка