fstream 产生非常奇怪的行为
fstream produces REALLY weird behavior
当我将双精度写入文件流,然后写入一个整数时,整数作为额外数字附加到双精度,我不知道为什么会这样。有人可以为我解释一下吗?最小示例:
#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字节)
- 它跳回到缓冲区的开头
- 它读取一个double类型的值(8字节)
- 打印值(显示
3.140000
)
实际情况:
程序输出 3.143600
- 我完全不知道为什么会这样。这是零意义。如果我改变初始值,比如从 3.14
到 18.3204
,那么它会输出 18.320436
。发生什么事了?
对流进行操作时,<<
和 >>
执行格式化访问。忽略幕后巫术,<<
写入字符串而 >>
读取字符串。所以
s << 3.14;`
将 3.14 转换为字符串并将该字符串写入文件。与 s << n;
相同。
您现在有一个包含字符“3.1436”的文件。
s >> d;
将文件作为字符串读取,寻找分隔空格或任何其他不能转换为双精度值的字符。由于文件中没有分隔 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 我的儿子!字节的顺序...
It writes the value 3.14 to the file (8 bytes)
It writes the value 36 to the file (4 bytes)
这不是发生的事情。 >>
和 <<
以及朋友以人类可读的形式读写值。
s << 3.14;
将数字 3、句号、数字 1 和数字 4 写入文件(4 个 ASCII 字符)。
s << 36;
将数字 3 和数字 6 写入文件(2 个 ASCII 字符)。
文件然后包含 6 个 ASCII 字符:一个 3、一个句点、一个 1、一个 4、一个 3 和一个 6。或者像任何正常人会写的那样:它包含 3.1436
。
s >> d;
从文件中按字符读取数字,直到找到一个看起来不像数字的字符,然后将读取的字符转换为数字(与他们如果您将它们键入 cin
),则会被转换。它读取 3,句点,1、4、3、6,然后生成数字 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);
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字节) - 它跳回到缓冲区的开头
- 它读取一个double类型的值(8字节)
- 打印值(显示
3.140000
)
实际情况:
程序输出 3.143600
- 我完全不知道为什么会这样。这是零意义。如果我改变初始值,比如从 3.14
到 18.3204
,那么它会输出 18.320436
。发生什么事了?
对流进行操作时,<<
和 >>
执行格式化访问。忽略幕后巫术,<<
写入字符串而 >>
读取字符串。所以
s << 3.14;`
将 3.14 转换为字符串并将该字符串写入文件。与 s << n;
相同。
您现在有一个包含字符“3.1436”的文件。
s >> d;
将文件作为字符串读取,寻找分隔空格或任何其他不能转换为双精度值的字符。由于文件中没有分隔 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 我的儿子!字节的顺序...
It writes the value 3.14 to the file (8 bytes)
It writes the value 36 to the file (4 bytes)
这不是发生的事情。 >>
和 <<
以及朋友以人类可读的形式读写值。
s << 3.14;
将数字 3、句号、数字 1 和数字 4 写入文件(4 个 ASCII 字符)。
s << 36;
将数字 3 和数字 6 写入文件(2 个 ASCII 字符)。
文件然后包含 6 个 ASCII 字符:一个 3、一个句点、一个 1、一个 4、一个 3 和一个 6。或者像任何正常人会写的那样:它包含 3.1436
。
s >> d;
从文件中按字符读取数字,直到找到一个看起来不像数字的字符,然后将读取的字符转换为数字(与他们如果您将它们键入 cin
),则会被转换。它读取 3,句点,1、4、3、6,然后生成数字 3.1436。