代码的输出显示了Student结构的所有变量的乱码值。当显示功能运行时。
我在二进制文件的每个添加和显示功能中都包含相关代码。
对于第二个函数,每次for循环运行时,seekg
指针是否自动移动以读取下一条记录?
//Student struct
struct Student
{
char name [30];
float labTest;
float assignments;
float exam;
};
//Writing function
afile.open(fileName,ios::out|ios::binary);
Student S;
strcpy(S.name,"test");
S.labTest = rand()%100+1;
S.assignments = rand()%100+1;
S.exam = rand()%100+1;
afile.write(reinterpret_cast<char*>(&S),sizeof(S));
afile.close();
//Reading function
afile.open(fileName,ios::in|ios::binary);
afile.seekg(0,ios::end);
int nobyte = afile.tellg();
int recno = nobyte / sizeof(Student);
Student S;
//Loop and read every record
for(int i = 0;i<recno;i++)
{
afile.read(reinterpret_cast<char*>(&S),sizeof(S));
cout << "Name of Student: " << S.name << endl
<< "Lab mark: " << S.labTest << endl
<< "Assignment mark: " << S.assignments << endl
<< "Exam mark: " << S.exam << endl << endl;
}
afile.close();
答案 0 :(得分:3)
您的代码存在很多问题:
调用写入函数将永久覆盖最后写入的数据集。您必须添加:ios::append
,以便在您之前编写的最后一个数据后面写入新数据。
使用afile.seekg(0,ios::end);
移动以获得tellg
文件大小后,您必须返回文件的开头才能阅读afile.seekg(0,ios::beg)
看起来您使用char数组来存储字符串。这不是c ++风格!你如何使用它很危险。如果使用strcpy,则可以复制长度超过为其保留的空间的字符串。所以你应该更喜欢std::string
。但是你不能简单地编写一个以std::string
为二进制的结构!要获得选中的副本,您可以使用strncpy
,但这仍然不是c ++;)
对于第二个函数,每次for循环运行时,seekg指针是否会自动移动以读取下一条记录?
是的,文件位置移动,每次成功读写。
通过简单地转储内存内容来编写二进制数据的一般注释: 这不是一个好主意,因为如果使用相同的机器类型和相同的编译器选项,则只能读回该数据。这意味着:具有不同字节序的机器将读取完全损坏的数据。另外一个不同的整数类型(32位对64位)将破坏该代码!
因此,您应该花一些时间以便携方式序列化数据。有很多库可用于读/写复杂的数据类型,如std :: string或容器类型。
使用SO的提示:
请提供每个人都可以简单地剪切和粘贴和编译的代码。我不知道你的Student
结构是什么。所以我采取了很多假设!你的struct真的使用char []吗?我们不知道!
#include <iostream>
#include <fstream>
#include <cstring>
const char* fileName="x.bin";
struct Student
{
char name[100]; // not c++ style!
int labTest;
int assignments;
int exam;
};
// Writing function
void Write()
{
std::ofstream afile;
afile.open(fileName,std::ios::out|std::ios::binary|std::ios::app);
Student S;
strcpy(S.name,"test"); // should not be done this way!
S.labTest = rand()%100+1;
S.assignments = rand()%100+1;
S.exam = rand()%100+1;
afile.write(reinterpret_cast<char*>(&S),sizeof(S));
afile.close();
}
void Read()
{
//Reading function
std::ifstream afile;
afile.open(fileName,std::ios::in|std::ios::binary);
afile.seekg(0,std::ios::end);
int nobyte = afile.tellg();
int recno = nobyte / sizeof(Student);
afile.seekg(0, std::ios::beg);
Student S;
//Loop and read every record
for(int i = 0;i<recno;i++)
{
afile.read(reinterpret_cast<char*>(&S),sizeof(S));
std::cout << "Name of Student: " << S.name << std::endl
<< "Lab mark: " << S.labTest << std::endl
<< "Assignment mark: " << S.assignments << std::endl
<< "Exam mark: " << S.exam << std::endl << std::endl;
}
afile.close();
}
int main()
{
for ( int ii= 0; ii<10; ii++) Write();
Read();
}