Witam.
Na początek może wkleję trochę kodu i poniżej napiszę o co chodzi
struct Szkolenie
{
int ID;
string nazwa;
int rok;
string nazwisko;
};
struct Uczestnik
{
int ID;
string nazwisko;
int ileSzkolen; //taki "sizeof" tablicy, szczegóły niżej
int **tab2; //tablica o wymiarze 2 na X. Jest w niej ID szkolenia i ocena którą dostał (nie wiadomo ile szkoleń odbyto)
};
vector<Szkolenie*> szkolenia;
vector<Uczestnik*> uczestnicy;
Mamy dwie struktury, jedna z nich posiada dwuwymiarową dynamiczną tablicę. "Egzemplarze" struktur po stworzeniu są "pakowane" do wektorów.
Szkolenie * ptr = new Szkolenie();
cout << "Podaj ID, nazwe, rok i nazwisko prowadzacego szkolenie\n";
cin >> ptr->ID >> ptr->nazwa >> ptr->rok >> ptr->nazwisko;
szkolenia.push_back(ptr);
Można egzemplarze edytować, usuwać itp. ale nie w tym rzecz. Ogólnie w zadaniu jest wiele podpunktów, ale nie one są istotne.
Szkolenia i uczestników trzeba odczytywać i zapisywać binarnie.
Ze szkoleniami nie ma żadnych problemów:
Odczyt do wektora:
char nazwa[50];
cout << "Podaj nazwe pliku\n";
cin >> nazwa;
ifstream plik(nazwa, ios::binary);
if(plik.is_open())
{
int n;
plik.read((char*)&n, sizeof(int));
szkolenia.clear();
for (int i = 0; i < n; i++)
{
Szkolenie * ptr = new Szkolenie();
plik.read((char*)ptr, sizeof(Szkolenie));
szkolenia.push_back(ptr);
}
plik.close();
cout << "Pomyslnie wczytano plik\n";
}
else
{
cout << "Blad wczytania pliku\n";
}
Zapis z wektora do pliku:
char nazwa[50];
cout << "Podaj nazwe pliku do zapisu\n";
cin >> nazwa;
ofstream plik(nazwa, ios::binary);
if(plik.is_open())
{
int n = szkolenia.size();
plik.write((char*)&n, sizeof(int));
for(int i = 0; i < n; i++)
{
Szkolenie &ref = *szkolenia.at(i);
plik.write((char*)&ref, sizeof(Szkolenie));
}
plik.close();
cout << "Pomyslnie zapisano\n";
}
else
{
cout << "Blad przy probie otwarcia";
}
Problem jest gdy chcemy zapisać i wczytać uczestników.
Metodą niebinarną jest łatwo:
char nazwa[50];
cin >> nazwa;
ifstream plik(nazwa);
while(!plik.eof())
{
Uczestnik * ptr = new Uczestnik();
plik >> ptr -> ID;
plik >> ptr -> nazwisko;
plik >> ptr -> ileSzkolen;
ptr -> tab2 = new int *[ptr -> ileSzkolen];
for (int i = 0; i < ptr -> ileSzkolen; i++)
{
ptr -> tab2[i] = new int[2];
}
for(int i = 0; i < ptr -> ileSzkolen; i++)
{
plik >> ptr -> tab2[i][0];
plik >> ptr -> tab2[i][1];
}
uczestnicy.push_back(ptr);
}
plik.close();
uczestnicy.erase(uczestnicy.end()-1);
Ostatnia linijka usuwa ostatni element wektora, gdyż dodaje się uczestnik z ID 0, bez nazwy...
Jeśli ktoś wie gdzie tkwi błąd, ale jak można inaczej to mile widziana odpowiedź :)
Zapis:
char nazwa[50];
cin >> nazwa;
ofstream plik(nazwa);
for(int i = 0; i < uczestnicy.size(); i++)
{
plik << uczestnicy.at(i) -> ID << endl;
plik << uczestnicy.at(i) -> nazwisko << endl;
plik << uczestnicy.at(i) -> ileSzkolen << endl;
for (int j = 0; j < uczestnicy.at(i) -> ileSzkolen; j++)
{
plik << uczestnicy.at(i) -> tab2[j][0] << endl;
plik << uczestnicy.at(i) -> tab2[j][1] << endl;
}
}
plik.close();
Odczyt, zapis linijka po linijce i łatwo wrzucić ID z oceną do tab2.
Nie rozumiem zapisu / odczytu binarnego dlatego nie mogę tego zrobić.
int n;
plik.read((char*)&n, sizeof(int));
szkolenia.clear();
for (int i = 0; i < n; i++)
{
Szkolenie * ptr = new Szkolenie();
plik.read((char*)ptr, sizeof(Szkolenie));
szkolenia.push_back(ptr);
}
Tę składnie podpowiedział mi kolega, który też to gdzieś wyczytał i nie za bardzo wiemy :P
Więc najważniejsze, jak zrobić zapis / odczyt binarnie ?
Jak uniknać uczestnicy.erase(uczestnicy.end()-1); przy wczytywaniu
Wszelkie inne podpowiedzi dotyczące "kodzenia" mile widziane :)
Dzięki za odp.