2009-09-04 42 views
3

这是一个C++问题。我有一个包含字符串类:如何将字符串作为二进制文件写入文件?

class MyClass{ 
public: 
std::string s; 
}; 

我有MyClass的对象的数组:

MyClass * array = MyClass[3]; 

现在我想写数组作为二进制文件到文件中。我不能使用:

Ofstream.write((char *)array, 3 * sizeof(MyClass)) 

因为MyClass的大小不同。

如何使用Ofstream.write来达到目的?非常感谢。

回答

4

在C++中,通常使用BOOST serialization class

以编程方式完成如下操作:

写作:

 
std::ofstream ostream("myclass.bin",std::ios::binary); 
if (!ostream) return; // error! 
std::size_t array_size = 3; 
ostream.write(reinterpret_cast<char*>(&array_size),sizeof(std::size_t)); 
for(MyClass* it = array; it != array + array_size; ++it) 
{ 
    MyClass& mc = *it; 
    std::size_t s = mc.s.size(); 
    ostream.write(reinterpret_cast<char*>(&s),sizeof(std::size_t)); 
    ostream.write(mc.s.c_str(),s.size()); 
} 

阅读

 
std::ifstream istream("myclass.bin",std::ios::binary); 
if (!istream) return; // error! 
std::size_t array_size = 0; 
istream.read(reinterpret_cast<char*>(&array_size),sizeof(std::size_t)); 
array = new MyClass[array_size]; 
for(MyClass* it = array; it != array + array_size; ++it) 
{ 
    MyClass& mc = *it; 
    std::size_t s; 
    istream.read(reinterpret_cast<char*>(&s),sizeof(std::size_t)); 
    mc.resize(s); 
    istream.read(mc.s.c_str(),s.size()); 
} 
istream.close(); // not needed as should close magically due to scope 
+0

“for mc:0 ... array_size” 是伪代码,C++ 0x还是错字? – 2009-09-04 10:04:30

+0

考虑到两个例子之间的语法不同,必须是伪代码。 – MSalters 2009-09-04 11:21:11

+6

我认为伪代码会更好,因为它更通用,但我已经将其更改为更具体到C++ – 2009-09-04 19:43:10

-1

开启在二进制模式的流:

std::fstream filestream("file.name", std::ios::out | std::ios::binary); 
1

撰写insertion operator为MyClass的,像this,由一个写出其成员的流之一。然后创建一个遍历数组的循环,将每个成员写入流中。请记住在某一时刻写出数组大小,以便在读取文件时知道需要读取多少个成员。

而且,正如Klaim所说,确保您以二进制模式打开流。

1

这样做的一个很好的办法是重写<<运营商MyClass

ostream& operator << (ostream& output, const MyClass& myClass) 
{ 
    return output << myClass.Value; 
} 

然后,您可以简单地连载串出的MyClass直接进入文件流:

std::fstream fileStream("output", std::ios::out|std::ios::binary); 

for (int i = 0; i < 3; ++i) 
    fstream << array[i]; 
3

超载operator<<为你的类。你可以这样做:

ostream& operator<< (ostream& os, const MyClass& mc) 
{ 
    return os << mc.s /* << ... other members*/ << endl; 
} 
+0

定义运算符>>也是一个好主意。 – Bill 2009-09-04 15:09:21

1

你想写什么文件?在C++中,您不能对C.std :: string中的对象内容进行假设,例如通常包含指针,分配器,字符串长度和/或前几个字符。它肯定不会持有你从string :: data()得到的整个char []。如果你有一个std :: string [3],那么三个sring :: data()数组将会(几乎肯定)是不连续的,所以你需要三次写操作 - 每次调用只能写一个连续的数组。

相关问题