如何用C ++编写一个对象文件

时间:2010-03-04 00:59:56

标签: c++ file object string

我有一个带有多个文本字符串作为成员的对象。我想一次性将这个对象写入文件,而不是将每个字符串写入文件。我怎么能这样做?

7 个答案:

答案 0 :(得分:10)

您可以覆盖operator>>operator<<来读/写流。

示例Entry struct包含一些值:

struct Entry2
{
    string original;
    string currency;

    Entry2() {}
    Entry2(string& in);
    Entry2(string& original, string& currency)
        : original(original), currency(currency)
    {}
};


istream& operator>>(istream& is, Entry2& en);
ostream& operator<<(ostream& os, const Entry2& en);

实现:

using namespace std;

istream& operator>>(istream& is, Entry2& en)
{
    is >> en.original;
    is >> en.currency;
    return is;
}

ostream& operator<<(ostream& os, const Entry2& en)
{
    os << en.original << " " << en.currency;
    return os;
}

然后打开文件流,并为您调用的每个对象打开:

ifstream in(filename.c_str());
Entry2 e;
in >> e;
//if you want to use read: 
//in.read(reinterpret_cast<const char*>(&e),sizeof(e));
in.close();

或输出:

Entry2 e;
// set values in e
ofstream out(filename.c_str());
out << e;
out.close();

或者,如果您想使用流readwrite,那么您只需替换operator实施中的相关代码。

当变量在struct / class中是私有的时,你需要将operator声明为友元方法。

您可以实现任何您喜欢的格式/分隔符。当你的字符串包含空格时,使用getline()接受字符串和流而不是>>,因为operator>>默认使用空格作为分隔符。取决于你的分隔符。

答案 1 :(得分:6)

这叫做序列化。 SO上有许多序列化线程。

boost中还包含一个很好的序列化库。

http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html

基本上你可以做到

myFile<<myObject 

myFile>>myObject

使用boost序列化。

答案 2 :(得分:4)

如果你有:

struct A {
    char a[30], b[25], c[15];
    int x;
}

然后你可以用write(fh,ptr,sizeof(struct a))来编写它。

当然,这不是可移植的(因为我们没有保存“int”的结尾或大小,但这对你来说可能不是问题。

如果你有:

struct A {
    char *a, *b, *c;
    int d;
}

然后你不打算写这个对象;你想要序列化它。最好的办法是查看Boost库并使用它们的序列化例程,因为在没有反射的语言中这不是一个简单的问题。

答案 3 :(得分:1)

没有一种简单的方法,毕竟它是C ++,而不是PHP或JavaScript。

http://www.parashift.com/c++-faq-lite/serialization.html

Boost也有一些库:http://www.boost.org/doc/libs/release/libs/serialization ...就像Tronic已经提到的那样:)

答案 4 :(得分:1)

更好的方法是单独编写每个字段以及字符串长度。

作为替代方法,您可以创建一个char数组(或std::vector<char>)并将所有成员写入缓冲区,然后将缓冲区写入输出。

潜在的棘手是允许编译器在类或结构中的成员之间插入填充。使用memcpystd::copy将导致填充字节写入输出。

请记住,您需要编写字符串长度和内容或内容,后跟一些终止字符。

其他人会建议查看Boost序列化库。

答案 5 :(得分:0)

不幸的是,这通常不太可能。如果您的结构只包含纯数据(没有指针或复杂对象),您可以将它存储为一个块,但如果可移植性是一个问题,必须小心。填充,数据类型大小和字节序问题使这成为问题。

您可以使用Boost.Serialization来最小化正确的可移植和可版本化的searialization所需的代码量。

答案 6 :(得分:0)

假设您的目标如上所述,只需调用write()或fwrite()或其他任何东西来写出对象,您首先需要将字符串和其他对象数据复制到一个连续的内存块中。然后你可以通过一次调用写出()该内存块。或者,如果您的平台上有该调用,则可以通过调用writev()来执行向量写入。

也就是说,通过减少写入呼叫的数量,你可能不会获得太多收益。特别是如果你已经使用fwrite()或类似的,那么C库已经为你做了缓冲,所以无论如何多个小调用的成本是最小的。不要让自己经历许多额外的痛苦和代码复杂性,除非它实际上会做一些好事......