Witam. Mam problem tego typu iż nie mam pojęcia jak zapisać całą klasę do pliku po zakończeniu programu i jak ją odczytać z pliku po otwarciu programu. Mam klasę człowiek zawierającą 3 tablice (imie[20], nazwisko[20] i pesel[20]). Następnie stworzyłem : człowiek ludzik[100]; i teraz się zaczyna dla mnie magia jak całego ludzika przenieść do pliku. Próbowałem wielu sposobów ale niestety nie za bardzo chce mi to działać. Z programowania jestem noga a muszę zrobić taki prosty programik więc liczę że ktoś mi da łopatologiczny opis czego użyć do zapisu żeby było prosto i zrozumiale. Z góry dziękuję i czekam na waszą pomoc.
- Chcesz zapisać obiekty do pliku nie klasę ;)
- To sie nazywa serializacja
- Jeśli to C++ to używaj string a nie char[]
- Jeśli to C++ to używja <vector> a nie zwykłej tablicy
Ja to widzę tak:
tworzysz dodatkową klasę np. GrupaOsob w której masz ten <vector> obiektów klasy Osoba i metodę load() i save(). Metoda save() otwiera plik i zapisuje do pliku poprzedzielane spacją imie, nazwisko i pesel i tak dla każdej osoby w osobnej linii. Metoda load() otwiera plik, wczytuje te 3 składowe z pliku, konstruuje obiekt Osoba i dodaje go do <vectora>.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Osoba
{
private:
string imie;
string nazwisko;
string pesel;
public:
Osoba(string i, string n, string p):imie(i),nazwisko(n),pesel(p) {}
string toString()
{
return (imie+" "+nazwisko+" "+pesel+"\n");
}
};
class GrupaOsob
{
private:
vector<Osoba> osoby;
public:
void add(Osoba o)
{
osoby.push_back(o);
}
void save()
{
ofstream plik("plik.txt");
for(vector<Osoba>::iterator i = osoby.begin();i<osoby.end();i++)
plik<<i->toString();
plik.close();
}
void load()
{
ifstream plik("plik.txt");
while(plik)
{
string i,n,p;
plik>>i>>n>>p;
Osoba tmp(i,n,p);
osoby.push_back(tmp);
}
}
};
Mniej wiecej coś takiego.
Tak jest to c++. To co zrobiłeś wydaje się dla mnie dużo bardziej zrozumiałe niż to co dotychczas widziałem na necie. Bardzo dziękuję za pomoc. Gdybym miał jakieś problemy to się odezwę. Bardzo dziękuję !!
Znalazłem banalną w obsłudze (przynajmniej przy zapisie) funkcję którą już teraz bez problemu zastosowałem w moim programie i zapisuje mi dane do pliku tekstowego
void zapis_pliku(int miejsce)
{
FILE *plik;
if ( (plik = fopen("baza.txt","wt")) != NULL)
{
for (int i=0; i<miejsce; i++)
fprintf (plik, "%s %s %d \n", baza[i].imie, baza[i].nazwisko, baza[i].numer_pesel );
fclose (plik);
}
}
Jednak czy da sie analogicznie zrobić to w drugą stronę?? Jeżeli fprintf wpisał mi rekordy do pliku to czy mogę je jakos kolejno odczytać i przy uruchamiania programu wczytać do mojej tablicy??
- To jest funkcja w czystym C, po co komplikujesz sobie życie?
- Ta funkcja działa dokładnie tak samo jak moja funkcja save() z tą róznicą ze tutaj masz tablicę a ja miałem vector
- Napisałem też funkcję load() która dokona tego o czym piszesz... Nie raczyłeś przetestować mojego kodu? On jest w zasadzie kompletnym rozwiązaniem twojego problemu. Musisz tylko dopisać sobie metody manipulacji danymi ...
Bardzo dziękuję Ci za pomoc. Zastosowałem Twój pomysł u mnie w programie i teraz mam piękny odczyt i zapis. Bardzo dziękuję za szybką odpowiedz i gotowe rozwiązanie !!
siemka, mam pytanie odnośnie tego przykładu sprzed 6 lat ;) jakie może być przykładowe wykorzystanie takiej klasy GrupaOsob? W jaki sposób przekazać ten obiekt Osoba do klasy GrupaOsob (przez konstruktor klasy GrupaOsob?)
Z góry dziękuje za odpowiedź.
- Konkretnie tej klasy nie ma sensu wykorzystywać, podobną - chociażby dla statystyk CRM
- Chcesz mieć gwarantowanie niepusty obiekt Grupy? Trochę bez sensu, ale skoro chcesz to podobnie do
add()
.
chciałbym wykorzystać to w moim programie(prosty dziennik lotów) w ten sposób, że mam klasę lot która przechowuje informacje o tym locie gównie stringi, a jedna ze składowych klasy lot jest klasa pasażerowie (i zrobiłem zapisywanie tego lotu z/do pliku) i chciałbym, aby na składowej pasażerowie jako tablicy obiektów była możliwość dodania do tego lotu i oprócz tego abym mógł jeszcze edytować podczas działania programu ilość pasażerów itp. w czasie wykonywania programu. Więc się zastanawiam jak tu by wykorzystać vector (niedawno znalazłem na necie klasę vector).
struktura menu:
1.dodaj lot
2.wczytaj lot(wczytuje dane z pliku i tworzy obiekt lot)
3.dodaj pasażerów do lotu
4.Usuń pasażera/wszystkich;
5.Wyszukaj pasażera(szuka pasażera i pokazuje w jakim jest locie)
(punkty 3/4/5 nie są zaimplementowane)
Lot :
#ifndef LOT_H
#define LOT_H
#include "zaloga.h"
#include "personel.h"
#include "pasazer.h"
#include "listaosob.h"
#include <string>
using namespace std;
class Lot
{
private:
string nazwaLot;
string gstartLot;
string gladowLot;
string miejscStar;
string miejscLad;
//ListaOsob listaOsob;
public:
Lot() {}
Lot(string nazwaL, string startL, string ladowL, string miejscS, string miejscL);
void disp();
friend ostream & operator<< (ostream &wyjscie, const Lot &s);
friend void dodaj(Lot a);
};
#endif
#include <iostream>
#include "lot.h"
//#include <string>
using namespace std;
Lot::Lot(string nazwaL, string startL, string ladowL, string miejscS, string miejscL)
{
nazwaLot = nazwaL;
gstartLot = startL;
gladowLot = ladowL;
miejscStar = miejscS;
miejscLad = miejscL;
}
void Lot::disp()
{
cout << nazwaLot<<" | " << gstartLot<<" | " << gladowLot<<" | " << miejscStar<<" | " << miejscLad << endl;
}
ostream & operator<< (ostream &wyjscie, const Lot &s)
{
wyjscie <<s.nazwaLot<< s.gstartLot <<s.gladowLot <<s.miejscStar << s.miejscLad << endl;
return wyjscie;
}
Dodaj lot
#include <iostream>
#include <fstream>
#include <string>
#include "../lot.h"
using namespace std;
void dodaj()
{
cout << "Podaj nazwe lotu|godzina startu/ladowania|mijesce startu/ladowania" << endl;
string nazwaLot;
string gstartLot;
string gladowLot;
string miejscStar;
string miejscLad;
cin>>nazwaLot;
cin>>gstartLot;
cin>>gladowLot;
cin>>miejscStar;
cin>>miejscLad;
Lot lot(nazwaLot,gstartLot,gladowLot,miejscStar,miejscLad);
string lokalizacja = "dane/" + nazwaLot;
ofstream plik;
plik.open(lokalizacja.c_str(), ios::out | ios::app);//albo ios::in
plik <<nazwaLot<<"\n"<<gstartLot<<"\n"<<gladowLot<<"\n"<<miejscStar<<"\n"<<miejscLad;
plik.close();
ofstream listaLotow;
listaLotow.open("dane/listaLotow.txt", ios::out | ios::app);//albo ios::in
listaLotow << nazwaLot << " | " << gstartLot << " | " << gladowLot << " | " << miejscStar << " | " << miejscLad<<"\n";
listaLotow.close();
}
Wczytaj lot
#include <iostream>
#include <fstream>
#include <string>
#include "../lot.h"
#include <cstdlib>
using namespace std;
void wczytaj()
{
cout << ".::Lista lotow::." << endl;
string linia;
ifstream plik;
plik.open("dane/listaLotow.txt", ios::in);
if (plik.good() == true)
{
while (!plik.eof())
{
getline(plik, linia);
cout << linia << endl; //wyświetlenie linii
}
plik.close();
}
string nazwaLot;
string gstartLot;
string gladowLot;
string miejscStar;
string miejscLad;
cout << "wybierz lot do wczytania: " << endl;
string jakiLot;
cin >> jakiLot;
//dodane aby rodzielic dane w folderach
string lokalizacja = "dane/" + jakiLot;
ifstream plik2;
plik2.open(lokalizacja, ios::in);
if (plik2.good() == true)
{
getline(plik2, nazwaLot);
getline(plik2, gstartLot);
getline(plik2, gladowLot);
getline(plik2, miejscStar);
getline(plik2, miejscLad);
plik2.close();
}
if (nazwaLot.empty())
cout << "Nie ma takiego lotu" << endl;
else
{
Lot lot(nazwaLot, gstartLot, gladowLot, miejscStar, miejscLad);
lot.disp();
}
}
Pasazer
#ifndef PASAZER_H
#define PASAZER_H
#include "zaloga.h"
//#include <string>
using namespace std;
class Pasazer :public Zaloga
{
private:
int wagaBag;
public:
Pasazer()
{
wagaBag = 0;
imie = "none";
nazwisko = "none";
}
Pasazer(int waga, string im, string naz);
int GetWaga();
virtual string GetImie();
virtual string GetNaz();
string toString();
};
#endif
#include <iostream>
#include <string>
#include "zaloga.h"
#include "pasazer.h"
using namespace std;
Pasazer::Pasazer(int waga, string im, string naz) :Zaloga(im, naz)
{
wagaBag = waga;
}
int Pasazer::GetWaga()
{
return wagaBag;
}
string Pasazer::GetImie()
{
return imie;
}
string Pasazer::GetNaz()
{
return nazwisko;
}
string Pasazer::toString()
{
string a;
a = to_string(GetWaga());
return (a + " " + imie + " " + nazwisko + "\n");
}
ListaOsob
#ifndef LISTAOSOB_H
#define LISTAOSOB_H
#include <iostream>
#include "pasazer.h"
#include "personel.h"
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class ListaOsob
{
private:
vector<Pasazer> osoby;
public:
ListaOsob(vector<Pasazer> osoby_) : osoby(osoby_) {}
void add(Pasazer o);
void save();
void load();
};
#endif
#include <iostream>
#include "pasazer.h"
#include "personel.h"
#include "listaosob.h"
using namespace std;
void ListaOsob::add(Pasazer o)
{
osoby.push_back(o);
}
void ListaOsob::save()
{
ofstream plik("plik.txt");
for (vector<Pasazer>::iterator i = osoby.begin();i<osoby.end();i++)
plik << i->toString();
plik.close();
}
void ListaOsob::load()
{
ifstream plik("plik.txt");
while (plik)
{
string i, n;
int w;
plik >> i >> n >> w;
Pasazer tmp(w, i, n);
osoby.push_back(tmp);
}
}
Veviel napisał(a):
... która przechowuje informacje o tym locie gównie stringi
Bardzo trafnie zauważono, start, ładowność, ilość miejsc - same gównie stringi.
Veviel napisał(a):
Więc się zastanawiam jak tu by wykorzystać vector (niedawno znalazłem na necie klasę vector).
Z czym konkretnie masz problem?
Jak można wypisać na ekran obiekt typu ListaOsob?( jak mogła by wyglądać metoda tej klasy ).
np w ten sposób?
void ListaOsob::show()
{
for (vector<Pasazer>::iterator i = osoby.begin();i<osoby.end();i++)
cout << i->toString();
}
Dla klasy Lot
umiesz a dla klasy ListaOsob
- nie?
dla klasy Lot nie użyłem klasy vector.
I co z tego?
To z tego, że jak miałem klasę Lot to było mi łatwiej, bo nie miałem użytej klasy vector więc zczytałem dane z pliku wierszami i umieściłem w obiekcie tej klasy a tutaj mam Klase Lista obiektów i tablice obiektów innej klasy w tej klasie i ciężko mi było to ogarnąć ale pokombinowałem i zrobiłem coś takiego
void ListaOsob::show()
{
fstream plik;
plik.open("dane/osoby.txt", ios::in);
for (vector<Pasazer>::iterator i = osoby.begin() + 1; i < osoby.end()-1;i++)
{
cout << i->toString();
}
}
i działa.
Teraz przenieś to do operatora takiego jak ma Lot
Zresztą dla Pasazer
też należy zrobić tak samo przez operator.