我正在尝试编写一个程序,将学生记录保存在二进制文件中。当我写多个记录时,它只显示最后一个记录。如何显示超过最后一条记录?它与我输入信息的方式有关吗?
答案 0 :(得分:1)
显示的代码存在多个问题。
1)std :: string不是数组。当您将std :: string写入文件时,所有最终发生的事情都是在std :: string结构中编写原始二进制指针,或多或少,这恰好指向堆上实际动态分配的内存,其中实际字符串的内容在写入文件的原始进程中。
将std :: string视为指针。 std :: string对象管理指针,并负责为它分配内存。它实际上比指针更复杂,但为了讨论的目的,它只是一个指针。所以,当你有:
char *p;
in.write(&p, sizeof(p));
你最终在这里做的不是写实际的字符串,不管它是什么,而是p指向的内部存储器地址。所以,如果说实际指针p的值是内存地址0x40823f0e(只是一些随机内存位置),你最终会将这个内存地址写入文件(4或8字节,具体取决于你是否正在编写一个32位平台。)
您不能只将std :: strings-s读/写到文件中。所有你最终写入文件都是毫无意义的二进制垃圾,一旦读入,在读取它的完全不同的过程中不太可能有任何意义。最好的情况是你会得到无意义的结果。最糟糕的(也是最可能的)结果是内存损坏和崩溃。
您应该注意的一点是,sizeof()始终是一个常量,由编译器计算。这段代码总是最终向文件写入固定数量的字节,对吗?
所以,停下来想一想:你正在用一个文件写一个固定数量的字节,用sizeof()。当你在这个结构中的std :: string只有几个字符或一百万个字符时,这对你来说是否有意义? std :: string中的字符数没有固有的限制。它仅受您可用内存的限制。
2)create()在文件中写入一个空结构。在提示其内容之前。通常,首先要填写一些结构,然后将其写入文件。不是相反。
3)display()用ios::out
打开文件。也就是说,写作。打开文件进行写入,然后尝试从中读取,不会产生有用的结果。