2015-03-11 10 views
1

Вот мой код до сих пор:C: Fread не читает весь блок

#include <stdio.h> 
#include <stdint.h> 

#define N_DET 432 
#define N_PROJ 500 

int readSinogram(uint16_t mess[],char filename[], int sample){ 
    //init 
    FILE *fp; 
    int i; 
    //open file 
    fp=fopen(filename,"r"); 
    //read sinogram 
    fseek(fp,sizeof(uint16_t)*N_DET*N_PROJ*sample*2,SEEK_SET); //move pointer 
    fread(mess,sizeof(uint16_t),N_DET*N_PROJ,fp); //read sinogram 
    return 0; 
}; 


int main() 
{ 
    uint16_t mess[N_DET*N_PROJ]; 
    char filename[]="C:\\Path\\MyFile.fxc"; 
    double curr; 
    int i,DET,PROJ; 

    readSinogram(mess,filename,0); //read the data 

    printf("\nDET?"); //ask for input 
    scanf("%u", &DET); 
    printf("\nPROJ?"); 
    scanf("%u", &PROJ); 

    curr=mess[DET+N_DET*PROJ]; //get the data 
    printf("Data: %f",curr); //print the data 

    return 0; 
} 

Об этом говорится в .fxc файл, который только двоичный файл, содержащий uint16_t отформатирован номера. «readSinogram» считывает один набор данных, который содержит номера N_DET * N_PROJ. (Указатель перемещается в два раза по размеру блока, потому что в файле есть чередующиеся блоки из двух измерений.) После прочтения его можно поместить в DET и PROJ и посмотреть данные на данный момент.

Пока все работает нормально. Данные верны для определенного диапазона данных, но при запросе слишком больших DET и/или PROJ данные неверны. У меня есть тот же файл, что и в Matlab, и он может подтвердить, что данные в нем прекрасны.

Чтобы быть более точным: каждый указатель выше [DET + N_DET * PROJ]> 248835 вернет 52428 вместо правильного значения (от 0 до 4088). Значения до тех, которые работают нормально. Поэтому, наверное, должно быть что-то неправильно с массивом «беспорядок» над этим индексом.

Что я делаю неправильно? Заранее спасибо!

+2

Вы читаете из двоичного файла с режимом '' r "', а не '' rb "'. – cremno

+1

Режим '' r "' является синонимом режима '' rb "' на большинстве платформ, отличных от Windows. Тем не менее, это хорошая форма, чтобы указать '' rb '', когда данные не известны или считаются текстовыми. Однако не похоже, что это связано с вашей проблемой. –

+0

sizeof (int)? ваш определяет значение по умолчанию для int, поэтому, если ваш sizeof (in) равен 16, вы можете изменить их значения на long int, используя суффикс L –

ответ

1

вам нужно выделить больший массив, чтобы добраться до значения индекса больше, чем 248835 в настоящее время у вас есть следующие определяет

#define N_DET 432 
#define N_PROJ 500 

, что приводит к размеру массива 432*500 = 216000

теперь, если ваша индексация массива при значении 248835 > 216000 вы получите доступ к памяти из выделенной памяти для массива, которая приведет к неопределенным поведением. Вам нужен массив большего размера, который вмещает более 248835 записей. простой #define N_DET 500 сделал бы это, но вы должны убедиться, что это требование. Базовая проверка индекса было бы полезно, чтобы избежать иметь отказа от проблем диапазона то на линиях

#define MAX_RANGE 500*500 
if((DET+N_DET*PROJ) < MAX_RANGE) 
    curr=mess[DET+N_DET*PROJ]; //get the data 
else 
    //error handling 

вы также должны обработки ошибок в fopenfseek и проверить возвращение на fread плюс опционально можно закрыть открытый файл discriptor по close(fd)

+0

Это верно, конечно. Я не правильно делал математику, когда писал вопрос. Я случайно вычислил '[DET + N_PROJ * PROJ]' при получении последнего возможного индекса для публикации здесь. Как уже упоминалось, изменение режима fopen на «rb» действительно решило проблему. Я делаю некоторые проверки ошибок с возвращаемыми значениями, я просто сократил код для отправки здесь. В любом случае спасибо! – Dominic

Смежные вопросы