2017-06-19 81 views
1

當我寫一個double到一個文件流,然後寫一個整數,整數作爲額外數字附加到雙精度,我不知道爲什麼會發生。有人可以爲我解釋這個嗎?小例子:fstream產生真正奇怪的行爲

#include <iostream> 
#include <fstream> 

int main() 
{ 
    std::fstream s("test.bin", std::fstream::binary | std::fstream::trunc | std::fstream::in | std::fstream::out); 
    s << 3.14; 
    int n = 36; 
    s << n; 
    s.seekp(0); 
    double d; 
    s >> d; 
    printf("%f\n", d); 
} 

我期待發生的事情:

  • 程序會打開一個名爲TEST.bin,燒寫
  • 它的價值3.14寫入文件(8個字節)
  • 它將值36寫入文件(4字節)
  • 它跳回到緩衝區的開頭
  • 它讀取雙型值(8個字節)
  • 它打印(顯示3.140000

值實際發生的: 方案產出3.143600 - 我完全不知道爲什麼發生。它毫無意義。如果我改變初始值,比如從3.1418.3204,那麼它輸出18.320436。發生了什麼?

+2

使用'std :: cout'而不是一些輸出文件流。然後問自己,你會怎麼決定,你是一個簡單的'雙提取算法,在哪裏*停止*閱讀數字。你的輸出'double'和輸出'int'之間沒有空格。你意識到這是*格式*輸出,*正確*? – WhozCraig

+0

它是不是把double值寫成8個純字節? –

+2

不,'<<'執行格式化輸出,而不是二進制輸出,即使使用'std :: fstream :: binary'。 – Barmar

回答

2

它寫入值3。14到文件(8個字節)
它的值36寫入文件(4個字節)

這是不會發生什麼變化。 >><<和朋友以人類可讀的形式讀取和寫入數值。

s << 3.14;將數字3,句號,數字1和數字4寫入文件(4個ASCII字符)。 s << 36;寫入數字3,數字6寫入文件(2個ASCII字符)。

然後該文件包含6個ASCII字符:a 3,句號,1,a 4,a 3和a 6.或者正如任何普通人寫的一樣:它包含3.1436

s >> d;通過文件中的字符讀取一個數字,直到它找到一個看起來不像數字的字符,然後將它讀取的字符轉換爲數字(與鍵入時它們將被轉換的方式相同他們到cin)。它讀取3,句號1,4,3,6,然後生成數字3.1436。

0

當在流上操作時,<<>>執行格式化訪問。忽略幕後伏都教,<<寫入字符串,>>讀取字符串。所以

s << 3.14;` 

把3.14變成一個字符串,並將字符串寫入文件。與s << n;相同。

您現在有一個包含字符「3.1436」的文件。

s >> d; 

將文件讀取爲字符串,查找分隔空白或任何其他無法轉換爲double值的字符。由於文件中沒有分隔3.14和36,所以3.1436作爲單個數字被讀回。

你需要做的是使用原始,未格式化的讀取和寫入:

#include <iostream> 
#include <fstream> 

int main() 
{ 
    std::fstream s("test.bin", 
        std::fstream::binary | std::fstream::trunc | 
         std::fstream::in | std::fstream::out); 
    double d = 3.14; 
    int n = 36; 
    if (s.write((char*) &d, sizeof(d)) && 
     s.write((char*) &n, sizeof(n))) 
    { 
     s.seekp(0); 
     if (s.read((char*) &d, sizeof(d))) 
     { 
      std::cout << d; 
     } 
     else 
     { 
      std::cerr << "failed to read\n"; 
     } 
    } 
    else 
    { 
     std::cerr << "failed to write\n"; 
    } 
} 

務必測試IO,以確保它成功了。

也被警告,這不是所有的便攜式。在一臺機器上寫入的文件不能保證在另一臺機器上可讀而不必太在意。 int s可能有不同的尺寸,謹防the endian我的兒子!該字節順序...

Documentation on write

Documentation on read