Jak zapisać klasę do pliku?

Jak zapisać klasę do pliku?
MA
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad 6 lat
  • Postów:7
0

Witam, w poniższym kodzie próbuję zapisać dane do pliku. A konkretnie usiłuję zapisać klasę ksiazka która jest dodawana najpierw do stosu biblioteka, a następnie miałaby być zapisywana do pliku. Niestety coś mi nie wychodzi i dane nie zapisują się do pliku. Nie wiem co robię źle, proszę o rady.

Kopiuj
#include <iostream>
#include <string>
#include <stack>
#include <fstream>
using namespace std;

class ksiazka{
    public:
string nazwa, autor, wydawnictwo;
int cena, rok_wyd;
};

void dodaj(ksiazka *x){
cout<<"Podaj tytuł książki:"; cin>>x->nazwa;
cout<<"Podaj autora:";cin>>x->autor;
cout<<"Podaj wydawnictwo:";cin>>x->wydawnictwo;
cout<<"Podaj rok wydania książki:";cin>>x->rok_wyd;
cout<<"Podaj cenę:";cin>>x->cena;
}

void pokaz(ksiazka x){
cout<<"\n "<<x.nazwa<<"\n "<<x.autor<<"\n "<<x.rok_wyd<<"\n "<<x.wydawnictwo<<"\n "<<x.cena;
}
stack<ksiazka>biblioteka;
void push(const ksiazka &x){};
void pop(ksiazka &x){};

void zapiszdopliku(ksiazka x){

    fstream plik;
 plik.open("dane.txt" ,std::ios::in | std::ios::out);
    cout<<"\nzapisywanie do pliku...";
    getline(plik, x.nazwa);
    getline(plik, x.autor);
    getline(plik, x.wydawnictwo);
     plik<<x.cena;
     plik<<x.rok_wyd;
    plik.close();
}


int main()
{
    fstream plik;
    ksiazka x;
    push(x);
    dodaj(&x);
    zapiszdopliku(x);
    pokaz(x);
    return 0;
}
edytowany 3x, ostatnio: flowCRANE
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
0

Dlaczego myślisz, że getline() coś zapisuje do pliku? :-)


MA
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad 6 lat
  • Postów:7
0

Czyżbym pomyliła odczyt z zapisem? dopiero się uczę, więc proszę o wyrozumiałość. Próbowałam też robić coś z

Kopiuj
plik.write(&ksiazka, sizeof(ksiazka))

ale nie działało

edytowany 1x, ostatnio: flowCRANE
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
1

Konstrukcja z plik.write(&ksiazka, sizeof(ksiazka)) niestety nie zadziała, ponieważ wewnątrz swojej struktury masz wskaźniki / obiekty (std::string w tym przypadku) - zostaną zapisane ich adresy, lecz nie wartości (możesz sobie obejrzeć hexedytorem tak wygenerowany plik, dla czystej ciekawości).

Pokombinuj z czymś takim:

Kopiuj
plik << x.nazwa;
plik << x.autor;
plik << x.wydawnictwo;
plik << x.cena;
plik << x.rok_wyd;

MA
dzięki za radę, spróbuję to pozamieniać i zobaczę czy zadziała :)
MA
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad 6 lat
  • Postów:7
0

Pozamieniałam, ale dalej nie działa, plik się nie tworzy. Czy źle zabrałam się za tworzenie pliku?

Kopiuj
#include <iostream>
#include <string>
#include <stack>
#include <fstream>
using namespace std;

class ksiazka{
    public:
string nazwa, autor, wydawnictwo;
int cena, rok_wyd;
};

void dodaj(ksiazka *x){
cout<<"Podaj tytuł książki:"; cin>>x->nazwa;
cout<<"Podaj autora:";cin>>x->autor;
cout<<"Podaj wydawnictwo:";cin>>x->wydawnictwo;
cout<<"Podaj rok wydania książki:";cin>>x->rok_wyd;
cout<<"Podaj cenę:";cin>>x->cena;
}

void pokaz(ksiazka x){
cout<<"\n "<<x.nazwa<<"\n "<<x.autor<<"\n "<<x.rok_wyd<<"\n "<<x.wydawnictwo<<"\n "<<x.cena;
}
stack<ksiazka>biblioteka;
void push(const ksiazka &x){};
void pop(ksiazka &x){};

void zapiszdopliku(ksiazka x){

    fstream plik;
 plik.open("dane.txt" ,std::ios::in | std::ios::out);
    cout<<"\nzapisywanie do pliku...";
     plik<<x.nazwa;
     plik<<x.autor;
     plik<<x.wydawnictwo;
     plik<<x.cena;
     plik<<x.rok_wyd;
    plik.close();
}


int main()
{
    fstream plik;
    ksiazka x;
    push(x);
    dodaj(&x);
    zapiszdopliku(x);
    pokaz(x);
    return 0;
}
edytowany 1x, ostatnio: mamba
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
2

Skoro Twoim celem jest tylko pisanie do pliku (a nie odczyt + pisanie jednocześnie, jak masz aktualnie), powinnaś wykorzystać klasę ofstream (output file stream, http://www.cplusplus.com/doc/tutorial/files/) - spróbuj tak:

Kopiuj
ofstream plik;
plik.open("dane.txt");
plik << x.nazwa;
plik << x.autor;
/* ... */
plik.close();

MA
Działa! A więc i ja działam i biorę się za dopisywanie kolejnych funkcji :)
Patryk27
Nie zapomnij zaptaszkować postu, który rozwiązuje problem (pod przyciskiem do łapkowania) - symbolicznie oznacza to wątek za rozwiązany.
MA
zaptaszkowane
tajny_agent
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad rok
  • Postów:1340
2

Od siebie tylko dodam:

Zamiast void dodaj(ksiazka* x) => void dodaj(ksiazka& x).
Jeśli widzisz, że argument funkcji jest wskaźnikiem to znaczy, że jest on opcjonalny, czyli możesz tam posłać np. nullptr. Funkcja dodaj do poprawnego działania wymaga obiektu ksiazka, więc powinien on być referencją.

Zamiast void zapiszdopliku(ksiazka x) => void zapiszdopliku(const ksiazka& x)
Jeśli potrzebujesz obiektu tylko do odczytu to przesyłaj go poprzez stałą referencję. Unikniesz niepotrzebnego kopiowania.


"I love C++. It's the best language in the world right now for me to write the code that i need and want to write"
~ Herb Sutter
MA
dzięki, pozamieniałam :)
MA
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad 6 lat
  • Postów:7
0

Dorobiłam funkcje do odczytu z pliku, tylko że znów ten sam problem bo nie działa (pomocy-znowu ;) ). A poza tym mam pytanie, czy da się zrobić tak, żeby dane najpierw były kładzone na stos, a potem zapisywane do pliku, a następnie przy odczycie z pliku wyświetlane były za pośrednictwem stosu? Bo generalnie chciałabym stworzyć tutaj bazę danych książek z użyciem dynamicznego kontenera danych (w tym przypadku stosu), przy okazji żeby te dane były zapisywane do pliku, i żeby był możliwy odczyt tych danych z pliku.

Kopiuj
#include <iostream>
#include <string>
#include <stack>
#include <fstream>
using namespace std;

class ksiazka{
    public:
string nazwa, autor, wydawnictwo;
int cena, rok_wyd;
};

void dodaj(ksiazka &x){
cout<<"Podaj tytuł książki:"; cin>>x.nazwa;
cout<<"Podaj autora:";cin>>x.autor;
cout<<"Podaj wydawnictwo:";cin>>x.wydawnictwo;
cout<<"Podaj rok wydania książki:";cin>>x.rok_wyd;
cout<<"Podaj cenę:";cin>>x.cena;
}

void pokaz(ksiazka x){
cout<<"\n "<<x.nazwa<<"\n "<<x.autor<<"\n "<<x.rok_wyd<<"\n "<<x.wydawnictwo<<"\n "<<x.cena;
}
stack<ksiazka>biblioteka;
void push(const ksiazka &x){};
void pop(ksiazka &x){};

void zapiszdopliku(const ksiazka& x){

ofstream plik;
 plik.open("dane.txt", ios::app);
    cout<<"\nzapisywanie do pliku...";
     plik<<x.nazwa;
     plik<<x.autor;
     plik<<x.wydawnictwo;
     plik<<x.cena;
     plik<<x.rok_wyd;
    plik.close();
}

void odczytajzpliku(ksiazka& x){
    fstream plik;
    plik.open("dane.txt", ios::in);
    plik>>x.nazwa;
    plik>>x.autor;
    plik>>x.wydawnictwo;
    plik>>x.rok_wyd;
    plik>>x.cena;
}


int main()
{
    ofstream plik;
    ksiazka x;

    push(x);
    odczytajzpliku(x);
    dodaj(x);
    zapiszdopliku(x);
    pokaz(x);
    return 0;
}
MasterBLB
Zrób @mamba nowy wątek na nowy problem, skoro ten oznaczyłaś jako rozwiązany.
MasterBLB
Ewentualnie modzi użyją swych mocy aby post do nowego wątku wydzielić. @kq, @furious programming?
Patryk27
Możemy tylko łączyć posty z poprzednimi (gdyby ktoś napisał n postów z rzędu), wydzielać niet.
MasterBLB
Takie buty...no to mamba, nie ominie cię porządkowanie na własną rękę.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.