2011-07-22 169 views
3

我想爲需要太多RAM的程序執行磁盤I/O操作。 我使用雙打矩陣,並認爲寫入磁盤的字節是最快的方式(我需要保持雙精度)。C++從二進制文件中寫入和讀取雙精度

如何做到攜帶方便?

我發現這個代碼(here),但筆者認爲這不是便攜式...

#include <iostream> 
#include <fstream> 

int main() 
{ 
    using namespace std; 

    ofstream ofs("atest.txt", ios::binary); 

    if (ofs) { 
     double pi = 3.14; 

     ofs.write(reinterpret_cast<char*>(&pi), sizeof pi); 
     // Close the file to unlock it 
     ofs.close(); 

     // Use a new object so we don't have to worry 
     // about error states in the old object 
     ifstream ifs("atest.txt", ios::binary); 
     double read; 

     if (ifs) { 
      ifs.read(reinterpret_cast<char*>(&read), sizeof read); 
      cout << read << '\n'; 
     } 
    } 

    return 0; 
} 
+2

這不是移植的,因爲'的sizeof(雙)'可能是跨平臺的不同。你需要檢查這個,否則示例代碼是可以的。 – spraff

+1

我更擔心'double'的字節順序,因爲它更有可能改變(特別是與任何嵌入式硬件交互時)。 –

+0

的確,儘管用「可能」來談論和思考是一種壞習慣。如果你真的關心可移植性,那麼它沒有程度。 – spraff

回答

5

如何與便攜做到這一點?

可移植性有不同的定義/級別。如果你所做的只是把它們寫在一臺機器上並在同一臺機器上讀取,那麼你關心的唯一可移植性就是這個代碼是否定義良好。 (是的)
如果你想在幾個不同的平臺上編寫可移植的代碼,你需要編寫字符串值,而不是二進制。

但是,請注意,您的代碼缺少適當的錯誤處理。它不檢查文件是否可以打開併成功寫入。

+0

你打我回答:) –

+0

@Luchian:我很抱歉。 ':)' – sbi

+0

我的可移植性「等級」是從個人計算機(在windows和linux/unix)到羣集。我想寫字節,因爲我需要最大速度和最小尺寸 – Andy

2

我認爲只有在寫入文件並在不同機器上讀取文件時纔會出現可移植性問題。但是,由於您說因爲RAM的限制而想要讀取/寫入文件,我只能假設您一次只能在一臺機器上執行讀取/寫入操作。這應該工作。

1

他可能一直指的是二進制表示,而不僅僅是sizeof。

C - Serialization of the floating point numbers (floats, doubles)

該規範沒有規定在所有浮點數的二進制表示。 大多數編譯器都遵循IEEE標準,因此如果您瞭解目標平臺,一個小小的單元測試應確保您所需的行爲。

+2

但是不要忘記,有些機器使用little-endian IEEE,有些使用big-endian IEEE格式 - 大致是Intel和「其他人」(PPC,SPARC ......)。 –

+0

是的,絕對。我認爲關鍵是您需要編寫測試以確保您希望定位的每個平臺上的有效性。 –

0

通常我用union來訪問字節。

union Data { 
    double val; 
    unsigned char str[sizeof(double)]; 
}; 

void saveToFile(double *values, int nvalues, const char *filename){ 
    int i; 
    FILE *arq; 
    Data num; 

    arq=fopen(filename,"w"); 
    if (arq == NULL) { 
     printf("Failed to open file \"%s\"\n", filename); 
     exit(0); 
    } 

    for(i=0; i<nvalues; i++){ 
     num.val = values[i]; 
     fwrite (num.str , sizeof(char), sizeof(double), arq); //ChunkSize 
    } 

    fclose(arq); 
} 

void loadFromFile(double *values, int nvalues, const char *filename){ 
    int i; 
    FILE *arq; 
    Data num; 

    arq=fopen(filename,"r"); 
    if (arq == NULL) { 
     printf("Failed to open file \"%s\"\n", filename); 
     exit(0); 
    } 

    for(i=0; i<nvalues; i++){ 
     fread(num.str, sizeof(char), sizeof(double), arq); 
     values[i] = num.val; 
    } 

    fclose(arq); 
} 
+0

......在這種情況下,它只是一個薄薄的單板,掩蓋了你真的只是在執行隱式'reinterpret_cast'的事實。因此,這與OP所要求的完全沒有任何不同或更具可移植性。如果你必須'reinterpret_cast',請說實話,明確地寫下來。 –

相關問題