Zapis klasy w pliku.

0

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.

0
  1. Chcesz zapisać obiekty do pliku nie klasę ;)
  2. To sie nazywa serializacja
  3. Jeśli to C++ to używaj string a nie char[]
  4. 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.

0

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ę !!

0

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??

0
  1. To jest funkcja w czystym C, po co komplikujesz sobie życie?
  2. 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
  3. 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 ...
0

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 !!

0

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ź.

0
  • 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().
0

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);
	}
}
0
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?

0

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();

}
0

Dla klasy Lot umiesz a dla klasy ListaOsob - nie?

0

dla klasy Lot nie użyłem klasy vector.

0

I co z tego?

0

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.

0

Teraz przenieś to do operatora takiego jak ma Lot
Zresztą dla Pasazer też należy zrobić tak samo przez operator.

1 użytkowników online, w tym zalogowanych: 0, gości: 1