【问题标题】:C: fread does not read the full blockC: fread 没有读完整块
【发布时间】:2015-05-13 19:44:07
【问题描述】:

到目前为止,这是我的代码:

#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)。这些值可以正常工作。所以我猜那个索引上方的“混乱”数组肯定有问题。

我做错了什么?提前致谢!

【问题讨论】:

  • 您正在读取模式为 "r" 而不是 "rb" 的二进制文件。
  • Mode "r" 与除 Windows 以外的大多数平台上的模式 "rb" 同义。不过,当数据未知或假定为文本时,最好指定"rb"。不过,这听起来与您的问题无关。
  • sizeof(int) ?您的定义默认为 int,因此如果您的 sizeof(in) 为 16,您可能希望使用后缀 L 将它们的值更改为 long int
  • 您将DETPROJ 声明为int 类型,但使用编辑描述符%u(对于unsigned int)来扫描它们。可能这也不能解释你的问题,但它仍然是一个错误。
  • @John Bollinger:char filename[]="C:\\Path\\MyFile.fxc"; 这一行很好地暗示了该平台是 MS/DOS 或 Windows。顺便说一句,可以在这些平台中使用正斜杠代替反斜杠。 Dominic 应该尝试 char filename[]="C:/Path/MyFile.fxc"; 只是为了娱乐和教育。

标签: c fopen fread fseek uint16


【解决方案1】:

你需要分配一个更大的数组来获得大于 248835 的索引值 目前你有以下定义

#define N_DET 432
#define N_PROJ 500

导致数组大小为432*500 = 216000

现在,如果您在值 248835 248835 &gt; 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

您还需要在fopen fseek 中进行错误处理,并检查fread 的返回值,另外您还可以选择通过close(fd) 关闭打开的文件描述符

【讨论】:

  • 这当然是正确的。我在写问题时没有正确地做数学。我在获取此处发布的最后一个可能索引时意外计算了[DET+N_PROJ*PROJ]。如前所述,将 fopen 模式更改为“rb”确实解决了这个问题。我对返回值进行了一些错误检查,我只是缩短了在此处发布的代码。无论如何,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
  • 2021-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多