Как прочитать двоичный файл неизвестной формы на С++?

У меня есть двоичный файл с заголовком 3600 байт, 13483 трассы (столбца), каждая с заголовком 240 байт. Я хочу пропустить заголовки и прочитать значения данных в матрице.

Я могу получить некоторые значения из файла, но от seismicDataNH[50][40] до seismicDataNH[50][54] должно быть [13, 17, 12, 5, 19, 51, 29, -118, - 127, -127, -50, 126, 126, 126, -32], чего я не понимаю.

Я не уверен, что правильно понимаю fread(), читает ли он файл как одну длинную строку значений или как несколько строк? Я предполагаю один длинный ряд, может быть, поэтому он не работает.

Вот код, который я написал для чтения файла:

#include <iostream>

using namespace std;

#define N_SAMP 1990
#define M_TR 13483

char tempArray [N_SAMP*M_TR];
char seismicData[1990][13483];
char seismicDataNH[1750][13483];

int main()
{
    FILE*seismicFile;
    seismicFile = fopen("NVGT-88-06.sgy","rb");

    if (seismicFile!=NULL)
    {
        fseek(seismicFile, 3600*sizeof(char), SEEK_CUR);
        fread(tempArray, sizeof(char), N_SAMP*M_TR, seismicFile);
        puts("\n\nRead File successfully");

        int c = 0;
        for (int in=0; in<N_SAMP; in++)
        {
            for (int im=0; im<M_TR; im++)
            {
                seismicData[in][im] = tempArray[c];
                c++;
            }
        }

        puts("\nStored in matrix");


        // Make matrix values without header values
        for (int in=240; in < N_SAMP; in++)
        {
            for(int im=0; im < M_TR; im++)
            {
                seismicDataNH[in-240][im] = seismicData[in][im];
            }
        }
        puts("Removed header");



        puts("Test values: \n");
        for (int it = 40; it<55; it++)
        {
            printf("%d\n", seismicDataNH[50][it]);
        }

        fclose(seismicFile);

    }
    return 0;
}

и вот файл данных (.sgy), если кто-то хочет взглянуть на него: https://www.dropbox.com/s/y8aa99yqhfyacc8/NVGT-88-06.sgy?dl=0


person vhflat    schedule 22.09.2015    source источник
comment
Не могли бы вы также показать фактические данные, которые вы получаете?   -  person Some programmer dude    schedule 22.09.2015
comment
Кроме того, единственная часть кода, которую вы показываете, является C++, это включаемый файл и оператор using вверху. Остальное могло быть получено из программы на чистом C.   -  person Some programmer dude    schedule 22.09.2015
comment
Я подозреваю, что вам просто нужно поменять местами цикл for, т.е. петля M_TR снаружи и петля N_SAMP внутри.   -  person Sander De Dycker    schedule 22.09.2015
comment
Когда я запускаю его, я получаю: Прочитанный файл успешно сохранен в матрице Удаленный заголовок Тестовые значения: -18 -42 -74 -101 -103 -77 -34 10 37 39 23 1 -11 -9 5   -  person vhflat    schedule 22.09.2015
comment
Если я поменяю местами петли, я не думаю, что seismicData[in][im] = tempArray[c]; больше не будет работать. Здесь я предполагаю, что fread() читает двоичный файл как один длинный массив строк.   -  person vhflat    schedule 22.09.2015
comment
@vhflat: попробуйте;) Судя по вашему описанию, имеется 13483 последовательных блока по 1990 байт (включая 240 для заголовка). Если это так, то ваши циклы for вложены неправильно.   -  person Sander De Dycker    schedule 22.09.2015
comment
Затем я получаю результат [-30 -1 5 -14 -30 -22 -12 -22 -42 -60 -50 -19 4 12 10], что все равно неверно. Если циклы неправильные, означает ли это, что массив seismicData должен быть и наоборот?   -  person vhflat    schedule 22.09.2015
comment
@vhflat: посмотри мой ответ   -  person Sander De Dycker    schedule 22.09.2015


Ответы (1)


Из вашего описания 13483 последовательных блока по 1990 байт (включая 240 для заголовка).

Это означает, что у вас неправильное вложение цикла for и индексация массива.

Измените определения массива на:

char seismicData[M_TR][N_SAMP];
char seismicDataNH[M_TR][N_SAMP-240];

И два вложенных цикла for:

for (int im=0; im<M_TR; im++)
{
    for (int in=0; in<N_SAMP; in++)
    {
        seismicData[im][in] = tempArray[c];
        c++;
    }
}

соотв. :

for(int im=0; im < M_TR; im++)
{
    for (int in=240; in < N_SAMP; in++)
    {
        seismicDataNH[im][in-240] = seismicData[im][in];
    }
}

Оставьте окончательный цикл for (который печатает данные) как есть.

Это должно дать вам ожидаемый результат (для меня это так).

person Sander De Dycker    schedule 22.09.2015
comment
Благодарю вас! Я представлял себе двоичный файл как «матрицу» значений, в которой строки считываются построчно и последовательно помещаются в массив. Последовательные блоки по 1900 байт имеют гораздо больше смысла. - person vhflat; 22.09.2015