1

由于我是本地 FORTRAN 程序员,因此我提前为我缺乏 c 知识而道歉。我得到了一些用于调试的 c 代码,它摄取二进制文件并将其解析为包含数百条记录(准确地说是 871 条)的输入文件,用于我正在使用的 Fortran 程序。问题是这些输入二进制文件和相关的 c 代码是在 Windows 环境中创建的。解析器读取二进制文件,直到到达文件末尾:

SAGE_Lvl0_Packet GetNextPacket()
{     

   int i;
   SAGE_Lvl0_Packet  inpkt;
   WORD              rdbuf[128]; 
   memset(rdbuf,0,sizeof(rdbuf));
   fprintf(stdout,"Nbytes: %u\n",Nbytes);//returns 224
   if((i = fread(rdbuf,Nbytes,1,Fp)) != 1)
      FileEnd = 1;
   else      
    {         
       if(FileType == 0)
          memcpy(&(inpkt.CCSDS),rdbuf,Nbytes);                 
       else  
          memcpy(&inpkt,rdbuf,Nbytes);
       memcpy(&CurrentPacket,&inpkt,sizeof(inpkt));
    }
    return inpkt;
}

因此,当代码到达数据包 872 时,此代码段应返回 FileEnd = 1。相反,解析器会尝试从(接近)文件末尾读取大量数据。我认为这会导致程序崩溃(至少在 Fortran 中会崩溃。c 会开始读取内存的下一部分吗?)幸运的是,稍后在代码中有一个 CRC 可以捕获解析器不是t 读取正确的数据并优雅地退出。

我认为问题源于 Windows 二进制文件中的二进制缓冲区大小和值比 Linux 中的更大/不同。如果是这种情况,是否有一种简单的方法可以在 c 或 Linux 中将 Windows 的二进制文件转换为 Linux?如果我的假设有误,那么也许我需要再查看一下代码。顺便说一句,一个 WORD 是一个 unsigned short int,一个 SAGE_Lvl0_Packet 是一个 3 层结构,共有 106 个 WORD。

4

1 回答 1

1

我认为这里最大的问题是,当fread()指示文件结束时,FileEnd标志被设置,但函数最终仍然返回一个(无效的)清零数据包。不是特别坚固的设计。我假设调用者应该FileEnd在尝试使用刚刚返回的数据包之前进行检查,但是由于没有显示,这很可能是一个错误的假设。

此外,不知道数据包的样子,就无法判断各种memcpy()调用是否正确。memcpy()要求将 224 个字节复制到一个据说只有 212 个字节长的结构中的事实是非常有问题的。

可能还有其他问题,但这些是我目前看到的大问题。

于 2012-09-20T20:14:27.917 回答