2017-06-19 58 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