2012-09-20 20 views
1

由於我是原生的FORTRAN程序員,因此我提前道歉,因爲缺乏c知識。我得到了一些c代碼來調試哪個攝入二進制文件,並將其解析爲一個輸入文件,該文件包含我正在使用的一個Fortran程序的幾百條記錄(確切地說,就是871條記錄)。問題在於這些輸入二進制文件和關聯的c代碼是在Windows環境中創建的。分析器通過二進制讀取,直到到達文件的末尾:將Windows中生成的二進制數據文件轉換爲linux

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中會出現這種情況,是否會開始讀取下一部分內存?)幸運的是,後來在代碼中出現了一個CRC,可以發現解析器不是'讀取正確的數據並優雅地退出。

我認爲問題源於Windows二進制文件中的二進制緩衝區大小和值比Linux中的更大/不同。如果是這樣的話,有沒有一種簡單的方法可以在c或Linux中將Windows的二進制文件轉換爲Linux?如果我在我的假設中錯了,那麼也許我需要再看一遍代碼。順便說一句,WORD是一個unsigned short int,而SAGE_Lvl0_Packet是一個三層結構,總共有106個WORD。

+0

非常非常簡短的回答:feof。 – iced

回答

1

我覺得這裏最大的問題是,當fread()指示文件結束,FileEnd標誌置位,但功能最終還是返回一個(無效)置零的數據包。不是一個特別強大的設計。我假設調用者在嘗試使用剛剛返回的包之前應該檢查FileEnd,但由於沒有顯示,所以很可能這是一個錯誤的假設。

此外,不知道數據包是什麼樣子,不可能知道各種memcpy()調用是否正確。 memcpy()被要求將224字節複製到據說只有212字節長的結構的事實是非常成問題的。

可能還有其他問題,但這些是我目前看到的大問題。

+0

我可能是錯誤的數據包的實際大小。我這樣說是因爲有4個字定義爲(例如)WORD PacketType:10。我推測這意味着PacketType只有10位長,但PacketType仍可能佔用16位內存塊。 – DavidH

+0

對於沒有發佈剩餘的代碼,我表示抱歉 - 我知道這可能令人沮喪 - 但這是控制衛星的代碼,所以我不想在這裏發佈太多的代碼。 – DavidH