I am extremely new to C++ (and programming in general really) and am working on a project that has me stumped (not hard to do ha). The project involves Direct Access Files.
What I would to for a project like this is write some primitive functions for reading and writing whole records and updating the file header.
I would create POD type structs to store individual records that are to be read from or written to the data files.
For example:
struct header
{
uint32_t valid; // number of valid records
char pad[20]; // padding to make this object 24 bytes
};
struct record
{
char no[4]; // stock number
char desc[8]; // description
uint32_t count;
uint32_t test_part;
char pad[4]; // padding to make this object 24 bytes
};
A function to write the header (which is always at file position 0
):
std::iostream& write(std::iostream& ios, const header& h)
{
ios.clear(); // clear any errors
ios.seekg(0); // move to beginning of file
ios.write(reinterpret_cast<const char*>(&h), sizeof(h)); // write the header to file
return ios; // return the stream (for easy error detection/chaining)
}
Same thing to write a record at a specific position:
std::iostream& write(std::iostream& ios, const record& r, size_t pos)
{
ios.clear(); // clear any errors
ios.seekg(sizeof(header) + (sizeof(record) * pos)); // move to record's position
ios.write(reinterpret_cast<const char*>(&r), sizeof(r)); // write the record to file
return ios; // return the stream (for easy error detection/chaining)
}
You can then write an initialization function in terms of those primitives:
std::iostream& init(std::iostream& ios, size_t num)
{
// Update the header to zero records
header h;
h.valid = 0;
write(ios, h);
// create each record with a -1 (EOF) marker
record r;
r.test_part = uint32_t(-1);
// output 20 copies of that record.
for(size_t pos = 0; pos < num; ++pos)
write(ios, r, pos);
return ios;
}
Then invoke it all on a real file a bit like this:
int main()
{
assert(sizeof(header) == 24);
assert(sizeof(record) == 24);
// binary mode io!
std::fstream fs("records.dat", std::ios::in|std::ios::out|std::ios::binary);
if(!init(fs, 20))
{
std::cerr << "ERROR: initializing data file:" << std::endl;
return 1;
}
// ...
}
NOTE: This code is hastily written and completely untested and merely presented as an example of how this problem can be approached. Hopefully it will give you some ideas.
ALSO: Writing binary files like this is not very portable between systems or even between different versions of the same compiler on the same platform.
Firstly, you seem to have 5 member variables in your class although there are only 4 data in each item. That's dangerous.
After fixing that, I'd just read the whole file into a vector of those objects. For writing, just use a little loop to hop around the vector according to the next number.
You don't need all those getters and setters. Never mind what Grady Booch says: you are the only programmer and you can trust yourself not to screw up your own data. Even if you couldn't, you could just as easily screw it up with the setters as by directly accessing a public member variable.
Just read and parse the file with cin, scanf or whatever you prefer. If the fields are all fixed width then reading a known number of characters with fread is probably your simplest option. Use atoi to make numbers out of strings.