class Work{
public:
struct dane {
int id;
char typeOfWork[5];
char Title[50];
char Author_lastName[40];
char Author_name[50];
int year;
char Promotor_lastName[30];
char Promotor_name[40];
char keyWords[50];
char summary[1000];
};
dane dane1;
};
In another class, I enter all values to this variables and save it to a binary file.
I want to save all this input into a vector in another class called liblary
:
class liblary : Work{
vector<Work> vec; // here is problem i want to keep all this inputs in this vector
int how_many_works;
void get_data(){
//
// Up here i have inputs for all this variables but I didn't copy it
//
ofstream plik;
plik.open("dane.dat",ios::out | ios::binary | ios::app);
if(plik.is_open()){
plik.write((const char *) &dane1, sizeof(dane));
vec.push_back(dane); // Something like that to store all works in this vector but this ofc don;t work
plik.close();
}
};
Ofc, in method get_data()
, I didn't copy here all inputs of data, I did it just to show that that is in the liblary
class and includes a binary file. This is a liblary system for a student thesis. I want this in vector
because later I must add modify and searching methods in this OOP program.
Main question: How I can put all inputs what are getting saved to binary file, to vector.
CodePudding user response:
Okay, your code is a little odd, but it's not too bad. I'm going to ignore the oddness because you might actually have a reason for it.
Your vector is std::vector<Work>
, but you're doing a push_back
of a dane
. You either need to change to a vector<Work::dane>
or do vec.push_back(*this)
instead.
I would make one other change. I don't know why you have a nested structure, but that's fine. I think it's dangerous to have dane dane
the way you do, and I think it's doubly-dangerous you're leaving the contents willy-nilly.
I'd do this:
std::vector<dane> vec;
if(plik.is_open()){
dane myDane; // This is new, and then I use it instead of dane1
// populate myDane as needed...
plik.write((const char *) &myDane, sizeof(myDane));
vec.push_back(myDane); // Something like that to store all works in this vector but this ofc don;t work
plik.close();
}
That is, I'd use a local copy of your dane
so you're not mucking with the one inside your object -- unless there's a good reason you want it to be mucked with while loading your vector.
CodePudding user response:
Since you append the data I assume you want to load the data stored in a previous run. In this case open the file for both reading and writing, and read the elements from the file first and simply store any additional data written in the vector:
Simplified example only setting the summary of a single element, appending it and printing all summaries:
struct dane {
int id;
char typeOfWork[5];
char Title[50];
char Author_lastName[40];
char Author_name[50];
int year;
char Promotor_lastName[30];
char Promotor_name[40];
char keyWords[50];
char summary[1000];
};
class Library
{
std::vector<dane> m_contents;
std::fstream m_file;
public:
Library(std::filesystem::path const& fileName)
{
// open file with
// - input pos at the end (we want to know the number of elements) -> ate
// - output pos at the end (we want to append data) -> app
// - for reading and writing -> (in | out)
// - no special treatment of line breaks -> binary
m_file.open(fileName, std::ios::out | std::ios::in | std::ios::binary | std::ios::app | std::ios::ate);
if (!m_file.is_open())
{
throw std::runtime_error("could not open file " fileName.string());
}
auto existingDataSize = m_file.tellg();
if ((existingDataSize % sizeof(dane)) != 0)
{
throw std::runtime_error("corrupted data in file " fileName.string());
}
m_contents.resize(existingDataSize / sizeof(dane));
m_file.seekg(0, std::ios::beg);
m_file.read(reinterpret_cast<char*>(m_contents.data()), existingDataSize);
}
void WriteElement(dane const& element)
{
m_file.write(reinterpret_cast<char const*>(&element), sizeof(element));
m_contents.emplace_back(element);
}
void Print() const
{
for (auto& d : m_contents)
{
std::cout << d.summary << '\n';
}
}
};
int main()
{
Library lib("lib.dat");
dane d;
std::cin >> d.summary;
lib.WriteElement(d);
lib.Print();
}