C++ ostream::写入而不是写入整个结构?

C++ ostream::写入而不是写入整个结构?,c++,visual-studio-2012,C++,Visual Studio 2012,我正在尝试将各种值(如int和simple structs)导出到二进制文件中。下面是一些代码: #include <iostream> #include <fstream> #include <cstdint> using namespace std; template<class T> void writeToStream(ostream& o, T& val) { o.write((char*)&val, sizeof(T)); cout

我正在尝试将各种值(如int和simple structs)导出到二进制文件中。下面是一些代码:

#include <iostream>
#include <fstream>
#include <cstdint>
using namespace std;

template<class T> void writeToStream(ostream& o, T& val)
{
    o.write((char*)&val, sizeof(T));
    cout << o.tellp() << endl;  //always outputs 4
}

struct foo {
    uint16_t a, b;
};

int main()
{
    foo myFoo = {42, 42};
    ofstream test("test.txt", ios::binary);
    writeToStream(test, myFoo);
    test.close();
}

程序应生成一个4字节长的输出文件。但当我打开它时,它只有2个字节长。如果我将
myFoo.a
myFoo.b
更改为包含256个或更多值(需要存储超过1个字节),则文件长度将变为4个字节。我正在Win7上使用VisualStudio11开发者预览;我还没有检查其他系统或编译器上是否发生了同样的情况。对于256以下的a或b值,如何使其正确输出?

文件只能由理解其存储格式的程序读回。记事本++不了解文件的存储格式,因此无法读回文件并进行合理渲染。请使用记事本++能够理解的格式(如ASCII文本)写入文件,或者仅使用能够理解您写入文件格式的程序读取文件。

我已按如下方式清理了您的代码。虽然我不知道为什么旧代码会输出两个字节,但新代码会输出四个字节

#include <iostream>
#include <fstream>
#include <cstdint>
using std::cout;
using std::endl;
using std::uint16_t;
using std::ostream;
using std::ofstream;
using std::ios;

template <class T> void writeToStream(ostream& o, T& val)
{
    o.write(reinterpret_cast<char *>(&val), sizeof(T));
    cout << o.tellp() << endl;  //always outputs 4
}

struct foo {
    uint16_t a, b;
};

int main()
{
    foo myFoo = {42, 42};
    ofstream test("test.txt", ios::binary);
    writeToStream(test, myFoo);
    // Just let the stream "test" pass out of scope.
    // It closes automatically.
    //test.close();
    return 0;
}
#包括
#包括
#包括
使用std::cout;
使用std::endl;
使用std::uint16\t;
使用std::ostream;
使用std::of流;
使用std::ios;
模板无效写入流(ostream&o、T&val)
{
o、 写入(重新解释转换(&val),大小(T));

你知道如何确定文件的长度吗?我用记事本++打开它,它显示为256下的2个字符,否则为4。但是,如果我右键单击文件并单击“属性”,我会它显示了4个字节……我认为这就是你的问题所在;你试图通过在文本编辑器中查看来确定二进制文件的大小。如果你使用工具,文件大小实际上是非常复杂的。只需fopen()it,fseek()结束,ftell()看看它有多大。你正在处理的问题称为“序列化”在这里,使用普通的旧C函数进行编写会对您有所帮助,在这种情况下,您无法对ostream输出的内容进行精确控制,而将其读回会有更大的问题你可以准确地告诉它该做什么。或者使用文件浏览器或终端命令来确定文件大小……我想我被甩了,因为记事本++通常会显示空字符之类的东西。但是,我向一个十六进制编辑器确认记事本++是错误的。看起来你的程序和他的完全相同,而且它可以工作,因为他的勒迪也工作了。