Jak zapisać klasę do pliku?

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.

#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;
}
0

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

0

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

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

ale nie działało

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:

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

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

#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;
}
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:

ofstream plik;
plik.open("dane.txt");
plik << x.nazwa;
plik << x.autor;
/* ... */
plik.close();
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.

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.

#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;
}

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