Hi im trying to read in a binary file that i created from another set of codes. Eg. Using A.cpp to create the binary file and using B.cpp to read the file
For example: in A.cpp i have created a file using with following structure below
struct assignment
{
char atitle [MAX];
int weight;
int markupon;
double marks;
};
struct subjects
{
char code [MAX];
char subtitle [MAX];
int NoOfTask;
assignment AStructure [MAX];
int finalmarks;
grades grade;
};
In A.cpp i use the following code to get the number of records i have in the file and it works fine.
int getNoOfRecords (fstream& afile, char filename [])
{
afile.open (filename, ios::in | ios::binary);
if (!afile)
{
afile.close ();
return 0;
}
// move read marker point to end of
// the last record
afile.seekg (0, ios::end);
int totalBytes = afile.tellg ();
int noOfsubjects = totalBytes / sizeof (subjects);
afile.close ();
return noOfsubjects;
}
In B.cpp i have the following structures
struct studentassignment
{
char atitle [MAXN];
int weight;
int markupon;
double marks;
};
struct studentsubjects
{
char code [MAXN];
char subtitle [MAXN];
int NoOfTask;
studentassignment AStructure [MAXN];
int finalmarks;
char grade [MAXN];
};*
And in B.cpp i use the below code to get the number of records but the results im getting is different from what i get in A.cpp. For example: I enter 3 sets of data in A.cpp, when i read from B.cpp i only get a size of 2. The data that is read in from the file is incorrect too.
int NoOfRecords (fstream& afile, char filename [])
{
afile.open (filename, ios::in | ios::binary);
if (!afile)
{
afile.close ();
return 0;
}
afile.seekg (0, ios::end);
int totalBytes = afile.tellg ();
int noOfsubjects = totalBytes / sizeof (studentsubjects);
afile.close ();
return noOfsubjects;
}
Is there something that im doing wrong or is there just no way to read in the file using a different cpp file??
Im only a beginner at c++ if im wrong at anything pls let me know. thanks in advance
MVCE
A.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;
const int MAX = 80;
enum grades {HDist, Dist, Credit, Pass, Fail};
struct assignment
{
char atitle [MAX];
int weight;
int markupon;
double marks;
};
struct subjects
{
char code [MAX];
char subtitle [MAX];
int NoOfTask;
assignment AStructure [MAX];
int finalmarks;
grades grade;
};
int main ()
{
afile.open ("filename.dat", ios::out | ios::binary);
afile.seekg (0, ios::end);
subjects s;
cout << "Subject Code: ";
cin >> s.code;
cout << "Subject Name: ";
cin.ignore();
cin.getline(s.subtitle, MAX);
cout << "No of assessment task: ";
cin >> s.NoOfTask;
cout << endl;
for (int i = 0; i < s.NoOfTask; i++)
{
cout << "Task " << i+1 << " information" <<endl;
cout << "Title: ";
cin.ignore();
cin.getline(s.AStructure[i].atitle, MAX);
cout << "Weight: ";
cin >> s.AStructure[i].weight;
cout << "Upon: ";
cin >> s.AStructure[i].markupon;
cout << endl;
s.AStructure[i].marks = 0;
total = total + s.AStructure[i].weight;
}
afile.write (reinterpret_cast <const char *>(&s), sizeof (subjects));
afile.close ();
}
B.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;
const int MAXN= 80;
const int MAXN0= 10;
struct studentassignment
{
char atitle [MAXN];
int weight;
int markupon;
double marks;
};
struct studentsubjects
{
char code [MAXN];
char subtitle [MAXN];
int NoOfTask;
studentassignment AStructure [MAXN];
int finalmarks;
char grade [MAXN];
};
int NoOfRecords (fstream& , char []);
void getrecord(fstream& afile, char filename [] , int, studentsubjects);
int main()
{
fstream afile;
subjects b;
int size;
size = NoOfRecords (afile, "filename.dat");
cout << size << endl;
for (int i = 0; i < size; i++)
{
getrecord(afile, "filename.dat", i+1, b);
cout << b.code << endl;
}
}
int NoOfRecords (fstream& afile, char filename [])
{
afile.open (filename, ios::in | ios::binary);
if (!afile)
{
afile.close ();
return 0;
}
afile.seekg (0, ios::end);
int totalBytes = afile.tellg ();
int noOfsubjects = totalBytes / sizeof (studentsubjects);
afile.close ();
return noOfsubjects;
}
void getrecord(fstream& afile, char filename [], int i, studentsubjectsb)
{
afile.open (filename, ios::in | ios::binary);
afile.seekg ((i) * sizeof (studentsubjects), ios::beg);
afile.read (reinterpret_cast < char *>(&b), sizeof (studentsubjects));
afile.close ();
}
The last member in struct subjects
(used in A.cpp
) is grade
and it should be around 1-8 bytes.
The last member in struct studentsubjects
(used in B.cpp
) is char[80]
and it should be 80 bytes.
It means that the structure in B.cpp
will be bigger than one in A.cpp
.
As a result, if the same number of bytes are given and it is just the size of three struct subjects
, it won't sufficient for three struct studentsubjects
.
To avoid this type of mistake, you should write the declaretions of structures to read and write in a header file and use the header file from source codes that read and/or write the structures.