当我向文件流写一个double,然后写一个整数时,整数作为额外数字附加到double,我不知道它为什么会发生。有人可以帮我解释一下吗?最小的例子:
#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);
}
我期待发生的事情:
3.14
写入文件(8个字节)36
写入文件(4个字节)3.140000
) 实际发生的事情:
程序输出3.143600
- 我完全不知道为什么会这样。它没有任何意义。如果我更改初始值,例如从3.14
更改为18.3204
,则会输出18.320436
。发生了什么事?
答案 0 :(得分: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,一个4,一个3和一个6.或者正如任何普通人所写的那样:它包含3.1436
。
s >> d;
通过文件中的字符读取一个数字,直到找到一个看起来不像数字的字符,然后将读取的字符转换为数字(就像转换它们一样)如果你输入cin
)。它读取3,句号,1,4,3,6,然后产生数字3.1436。
答案 1 :(得分:0)
在对流进行操作时,<<
和>>
执行格式化访问。忽略幕后伏都教,<<
写字符串,>>
读取字符串。所以
s << 3.14;`
将3.14转换为字符串并将字符串写入文件。与s << n;
相同。
您现在有一个包含字符&#34; 3.1436&#34;的文件。
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
可能大小不同,请注意我的儿子the endian!字节的顺序......