2013-05-13 200 views
2

我是编程初学者,遇到问题。 我想写一个结构到我的二进制文件。我不确定结果。这里的结构:二进制文件应该是什么样子?

struct clientData 
{ 
    unsigned int id; 
    char name[25]; 
    char post[15]; 
    char degree[10]; 

    clientData(unsigned int, char*, char*, char*); 
}; 

正如你所看到的,我的结构包含一些字符串。 下面是主要问题: 我的字符串是否应该在最终的二进制文件中被重新转换(所以它们在应用程序(如记事本等)中无法读取? 因为我的结果看起来像这样(我不能添加图像,所以我就贴吧):

万里的EdgecombeМММММММММdocentММММММММpew1МММММММ

这是我怎么写二进制文件:

ofstream binary_1st("binary_input.dat", ios::out | ios::binary); 
... 
binary_1st.write((char*) &cl, sizeof(clientData)); 
... 
binary_1st.close(); 
+0

你想在二进制文件中使用什么格式? – 2013-05-13 16:38:31

+1

作为初学者,通常更容易坚持文本格式。 – MSalters 2013-05-13 16:39:50

+0

@MSalters我的学生和我的任务是使用二进制文件存储数据,所以我无法避免它:D – 2013-05-13 16:55:39

回答

0

你写了结构的文件原样,没有任何序列化或p ACKING。所以结构将被写入,因为它是字符串将是可读的(如果他们是在代码读取),数字将号码等

顺便说一句,这个M的在

Miles Edgecombe МММММММММdocent ММММММММpew1 МММММММ 

意味着字符在将字符串写入它们之前,结构中的数组不会被清零,因此末尾没有尾随零,因此'thrash'将写在末尾。

+0

在我的情况下最有趣的是数字被重新转换并且无法读取(带ID的第一个符号不可读,因此无法粘贴) – 2013-05-13 16:45:04

+0

这是因为文本编辑器试图将您的数字表示为ascii字符(或根据编码组)。如果这个数字不是有效的字符代码,它将不会在文本模式下正确显示。然而,十六进制编辑器会告诉你真正的价值。 – maverik 2013-05-13 16:46:34

+0

这就是我困惑的原因。十六进制编辑器显示我的十六进制值,但字符串根本没有改变:) – 2013-05-13 16:54:39

0

我的字符串应该在最终的二进制文件中被重新转换(所以它们 对于像记事本等应用程序是不可读的)?因为我的结果看起来像 这样(我不能添加图像,所以我只是将其粘贴):

不要担心这一点。你的字符串可能不包含换行符。任何将二进制文件转换为文本格式的代码都应该担心记事本& c。

你可能不应该发明自己的二进制格式。但是如果你确实需要的话,那么请留意以下几点。

  • 确保它包含版本信息。
  • 要清楚数据大小,可能用具有固定32位或64位大小的东西代替int
  • 将您的整数字节逐字节存储,以便它具有固定的endiannes。见http://linux.die.net/man/3/htons
  • 使用固定字符串编码。 UTF-8。
  • 确保您知道您的字符串如何终止。可以在它们前面粘贴一个大小,或者在字符串之后写出一个NUL字节(您的示例代码都不可以)。

更新:我只注意到我的答案可能是不适合初学者很清楚,但我不想把它做成了一篇文章。重点是,逐字存储结构可能不是一个好主意。如果您需要更详细的信息,请询问。

+0

我非常怀疑OP是否真的需要所有这些才能让他简单地玩转。虽然是的,但在创建便携式二进制格式时,这些要点非常重要,如果您只是保持较小的状态,则确实没有必要。 – 2013-05-13 16:48:15

+0

@ RichardJ.RossIII如果你只是坚持小国,文本格式更合适。如果你想以后能够读取数据,那么你就必须遵循Adrian的建议。 – 2013-05-13 16:52:37

+0

正确。虽然如果OP在玩,他应该坚持文本。解析二进制文件并不容易,但它更有用。 – 2013-05-13 16:53:46

0

如果您想让它在NotePad中可读,则需要将文本写入文本。使用<<运算符并使其超载如何表示数据。

要将数据写入文本:

std::ostream& operator<<(std::ostream& os, const clientData& obj) 
{ 
    os << obj.id << " " << obj.name << " " << obj.post << " " << obj.degree; 
    return os; 
} 

... 

binary_1st << cl << std::endl; 

否则,你有数据+一些不可读的编码数据。如果存储在char []中的字符串的长度小于数组的大小,即使您会在文件中看到垃圾。

+0

其实我想确保我以正确的方式使用二进制文件(我应该使用BINARY FILE来存储我的数据),但我不确定它是否是因为可读的字符串。对不起,我的英语,我希望你明白:) – 2013-05-13 16:46:47

+0

ios :: binary只是一个格式选项(如果我可以这样称呼它)流。它不会自动为您创建二进制文件。您可以选择格式。 – maverik 2013-05-13 16:48:15

+0

@AlesDokshanin:当你将文件中的数据写成二进制文件时,它可能是可读的(例如字符序列)。所以,不要担心。如果您希望写入的数据不可读,请在写入之前尝试对其进行加密或编码。 – deepmax 2013-05-13 16:50:30

相关问题