我正在读取/写入/存储学生作业标记。
我正在使用2结构
struct assessTask
{
char title [MAX];
int weight;
int markUpon;
float mark;
};
struct subject
{
char code [MAX];
char title [MAX];
int numTask;
assessTask task [MAX];
int finalMark;
UNIGrade grade;
};
我写函数的简短说明:(请告诉我这种风格是否正确)
// run if code is unique
strcpy(s[size].code, testcode);
afile.write (reinterpret_cast <const char *>(&s[size].code), sizeof (s));
cin.clear();
cin.ignore(MAX, '\n');
cout << "Subject Name: ";
cin.getline(s[size].title, MAX);
afile.write (reinterpret_cast <const char *>(&s[size].title), sizeof (s));
cout << "No of assessment tasks: ";
cin >> s[size].numTask;
afile.write (reinterpret_cast <const char *>(&s[size].numTask), sizeof (s));
Snippet of whats inside my binary file .dat
因此,在我退出程序后,存储.dat以供将来使用。 每次我打开程序,它都会检查.dat文件,我可以用它来查询或通过程序更新
void checkBinary(fstream& afile, const char fileName [], subject s[])
{
afile.open(fileName, ios::in | ios::binary);
int g = 0;
while (afile.read (reinterpret_cast <char *>(&s), sizeof (s)))
{
g++;
}
cout << g << endl;
if (g < 1)
{
createBinary (afile, "subject.dat", s);
}
else
{
readBinary (afile, "subject.dat", s);
}
afile.close();
}
void createBinary (fstream& afile, const char fileName [], subject s[])
{
afile.open (fileName, ios::out | ios::binary);
cout << "Begin the creation of binary file " << fileName << endl;
afile.write (reinterpret_cast <const char *>(&s), sizeof (s));
afile.close ();
cout << "Binary file " << fileName
<< " successfully created"
<< endl;
}
void readBinary (fstream& afile, const char fileName [], subject s[])
{
afile.open (fileName, ios::in | ios::binary);
afile.clear();
afile.seekg(0, ios::end);
int size = afile.tellg();
int noOfRecords = size / sizeof (s);
afile.seekg(0, ios::beg);
while (afile.tellg() < noOfRecords)
{
afile.read (reinterpret_cast <char *>(&s), sizeof (s));
/*
afile.read (reinterpret_cast <char *>(&s[start].code), sizeof (s));
afile.read (reinterpret_cast <char *>(&s[start].title), sizeof (s));
afile.read (reinterpret_cast <char *>(&s[start].numTask), sizeof (s));
for (int i = 0; i < s[start].numTask; i++)
{
afile.read (reinterpret_cast <char *>(&s[start].task[i].title), sizeof (s));
afile.read (reinterpret_cast <char *>(&s[start].task[i].weight), sizeof (s));
afile.read (reinterpret_cast <char *>(&s[start].task[i].markUpon), sizeof (s));
}
*/
}
afile.close();
}
由于某种原因,我必须在readbinary()中使用afile.clear(),否则返回给我的字节是-1。
我现在遇到的问题是我需要从.dat文件复制信息并将其存储在某处,以便在连续使用程序时,我仍然能够检索数据并在s []时显示它.code已输入。
需要注意的一些事项:
仍然是C ++的业余爱好者,如果我不理解某些背景,我会事先道歉
感谢任何帮助。 TKS!
答案 0 :(得分:0)
一些事情:
您需要afile.clear()
的原因是因为当您从流中读取时,您正在推进其正在读取的文件中的位置。你要做的第一件事就是阅读整个文件......所以任何进一步的读取当然都会在你读完文件后没有返回任何数据。在您使用clear()
这条线路错误:
while (afile.read (reinterpret_cast <char *>(&s), sizeof (s)))
sizeof(s)
将等于sizeof(subject*)
并且您正在阅读垃圾内存(我认为);这导致问题#3
不建议写这样的东西:
void checkBinary(fstream& afile, const char fileName [], subject s[])
因为你正在丢失数组的大小!在C和C ++中,函数参数不是数组(即使它们看起来像它们),它们是指向第一个元素的指针!当你传递一个阵列时,它就会衰变。指针。
为清楚起见,请注意以上行完全等于以下内容:
void checkBinary(fstream& afile, const char *fileName, subject *s)
最好像这样编写你的函数:
std::vector<subject> checkBinary(const std::string &fileName);
注意:文件名作为std::string
和 const引用传递,以避免不必要的副本。无需担心手动管理char
数组的详细信息及其生命周期(如果它在堆上分配)。
此外,返回vector
个subject
个对象,因为此函数通过从文件中读取它们来生成主题。 vector
知道它的大小,所以你永远不需要打扰sizeof
所以我可能会实现你的一个功能:
std::vector<subject> checkBinary(const std::string &fileName) {
// why pass the ifstream if you just open/close it in this function
// do it locally!
std::ifstream afile(fileName, ios::in | ios::binary);
subject s;
std::vector<subject> subjects;
// read each subject and then add them to the result array!
while (afile.read (reinterpret_cast <char *>(&s), sizeof (s))) {
subjects.push_back(s);
}
cout << subject.size() << endl;
// these will obviously need to be reworked as well to support the
// different methodology
if (subject.empty()) {
createBinary ("subject.dat", subjects);
} else {
// do we even NEED a readBinary? we just read them above!
}
// NOTE: since we made the ifstream locally, no need to close it
// explicitly! research the concept of RAII and make your code even simpler
// :-)
return subjects;
}