zapis/odczyt tablicy obiektów na dysk - binarnie/visualc++

0

Cześć , doszedłem do wniosku że zacznę się uczyć ;) - samodzielnie c++ , w ramach nauki własnej postanowiłem sobie napisać program ,(do celowo służący do prowadzenia i kontroli budżetu domowego),krytyka i optymalizacja mile widziana aczkolwiek przypominam że się uczę sam w miarę wolnego czasu więc błędy mogą być różnej "jakości" :)) . Problem mój polega na odczycie tablicy obiektów z dysku, znaczy teoretycznie się odczytuje ale odczytane wartości kompletnie nie pokrywają się z wartościami zapisanymi (chyba że błąd jest po stronie procedury zapisującej..?) .Proszę o ewentualną pomoc lub naprowadzenie ... .Pozdrawiam i dziękuję Witek

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
using namespace std ;

class wodomierz {
private:
	float stan_licznika ;
public:
	wodomierz () {stan_licznika=0;}
	~wodomierz () {}
	float podajstan () {return (stan_licznika);}
	void ustawstan (float stan) {stan_licznika=stan;}
	};

class mieszkanie {

float stawkaciepla ; float stawkazimna ; float kilowat ; float czynsz ; float opllicznik ; float inne1 ; float inne2 ; float inne3 ;
wodomierz cieplalazienka;wodomierz zimnalazienka;wodomierz cieplakuchnia;wodomierz zimnakuchnia;wodomierz licznikpradu;

public:
mieszkanie () {czynsz=390.0;opllicznik=6.50;kilowat=0.53;stawkaciepla=29.31;stawkazimna=11.08;inne1=0;inne2=0;inne3=0;}
~mieszkanie () {}
		
	void uczynsz (float Wczynsz) {czynsz=Wczynsz;}
	void uoplatelicznikowa (float Wopllicz) {opllicznik=Wopllicz;}
	void ustawkaciepla (float Wstan) {stawkaciepla=Wstan;}
	void ustawkazimna (float Wstan) {stawkazimna=Wstan;}
	void ukilowat (float Wstan) {kilowat=Wstan;}
	void uinne1 (float Winne1) {inne1=Winne1;}
	void uinne2 (float Winne2) {inne2=Winne2;}
	void uinne3 (float Winne3) {inne3=Winne3;}
	void ucieplalazienka (float Wstan) {cieplalazienka.ustawstan (Wstan);}
	void uzimnalazienka (float Wstan) {zimnalazienka.ustawstan (Wstan);}
	void ucieplakuchnia (float Wstan) {cieplakuchnia.ustawstan (Wstan);}
	void uzimnakuchnia (float Wstan) {zimnakuchnia.ustawstan (Wstan);}
	void ulicznikpradu (float Wstan) {licznikpradu.ustawstan (Wstan);}
	float pstawkaciepla (){return(stawkaciepla);}
	float pstawkazimna (){return(stawkazimna);}
	float pkilowat (){return(kilowat);}
	float pczynsz () {return (czynsz);}
	float poplatelicznikowa () {return (opllicznik);}
	float pinne1 () {return (inne1);}
	float pinne2 () {return (inne2);}
	float pinne3 () {return (inne3);}
	float pcieplalazienka () {return (cieplalazienka.podajstan ());}
	float pzimnalazienka () {return (zimnalazienka.podajstan ());}
	float pcieplakuchnia () {return (cieplakuchnia.podajstan ());}
	float pzimnakuchnia () {return (zimnakuchnia.podajstan ());}
	float plicznikpradu () {return (licznikpradu.podajstan ());}

};

mieszkanie * wskmieszkanie = new mieszkanie [12];

void wprowadzanie(short unsigned int miesiac)
{
	float dana=0;string odp=" ";
	system ("cls");
	cout <<"Aktualna stawka czynszu: "<<wskmieszkanie[miesiac].pczynsz()<<endl;
	cout <<"Aktualna stawka oplaty licznikowej: "<<wskmieszkanie[miesiac].poplatelicznikowa()<<endl;
	cout <<"Aktualna stawka za m3 cieplej wody: "<<wskmieszkanie[miesiac].pstawkaciepla()<<endl;
	cout <<"Aktualna stawka za m3 zimnej wody: "<<wskmieszkanie[miesiac].pstawkazimna()<<endl;
	cout <<"Aktualna stawka za kilowat:  "<<wskmieszkanie[miesiac].pkilowat()<<endl<<endl<<endl;
	cout <<"(1)\tStan cieplej wody kuchnia:  ?  "<<wskmieszkanie[miesiac].pcieplakuchnia()<<endl;
	cout <<"(2)\tStan zimnej wody kuchnia:  ?  "<<wskmieszkanie[miesiac].pzimnakuchnia()<<endl;
	cout <<"(3)\tStan cieplej wody lazienka:  ?  "<<wskmieszkanie[miesiac].pcieplalazienka()<<endl;
	cout <<"(4)\tStan zimnej wody lazienka:  ?  "<<wskmieszkanie[miesiac].pzimnalazienka()<<endl;
	cout <<"(5)\tStan licznika pradu:  ?  "<<wskmieszkanie[miesiac].plicznikpradu()<<endl;

	cout << "\nCzy bedzie zmiana stawki: ?  \n(c)zynszu\n(o)platy licznikowej\nc(i)eplej\nzi(m)nej\n(k)ilowata\nlicznikow (1,2,3,4,5)\nKo(n)iec  ? ";
	cin >> odp;
	cout<<endl;
	
	for (int x=1;x<=(odp.length());x++)
	{
	if (odp[x-1]=='n'){break ;};
	if (odp[x-1]=='c'){cout << "\nPodaj nowa stawke czynszu :  ";cin >> dana ;wskmieszkanie[miesiac].uczynsz(dana);};
	if (odp[x-1]=='o'){cout << "\nPodaj nowa stawke oplaty licznikowej ?   ";cin >> dana;wskmieszkanie[miesiac].uoplatelicznikowa(dana);};
	if (odp[x-1]=='i'){cout << "\nPodaj nowa stawke za m3 cieplej wody ?   ";cin >> dana;wskmieszkanie[miesiac].ustawkaciepla(dana);};
	if (odp[x-1]=='m'){cout << "\nPodaj nowa stawke za m3 zimnej wody ?   ";cin >> dana;wskmieszkanie[miesiac].ustawkazimna(dana);};
	if (odp[x-1]=='k'){cout << "\nPodaj nowa stawka za kilowat ?   ";cin >> dana;wskmieszkanie[miesiac].ukilowat(dana);};
	if (odp[x-1]=='1'){cout << "\nPodaj kuchnia ciepla :   ?  ";cin>>dana;wskmieszkanie[miesiac].ucieplakuchnia(dana);};
	if (odp[x-1]=='2'){cout << "\nPodaj kuchnia zimna :   ?  ";cin>>dana;wskmieszkanie[miesiac].uzimnakuchnia(dana);};
	if (odp[x-1]=='3'){cout << "\nPodaj lazienka ciepla :   ?  ";cin>>dana;wskmieszkanie[miesiac].ucieplalazienka(dana);};
	if (odp[x-1]=='4'){cout << "\nPodaj lazienka zimna :   ?  ";cin>>dana;wskmieszkanie[miesiac].uzimnalazienka(dana);};
	if (odp[x-1]=='5'){cout << "\nPodaj licznik pradu :   ?  ";cin>>dana;wskmieszkanie[miesiac].ulicznikpradu(dana);};
	};

return ;
	}
void statystyki (){
	return;
};
bool plik (){
	fstream plikdyskowy ;
	plikdyskowy.open ("d:\\wydatki.bin",ios::in|ios::binary);
	if( plikdyskowy.good() == true ) {plikdyskowy.close();cout<<"PLIK ISTNIEJE\n\n";system("pause");return (true);};
	cout<<"PLIK NIE ISTNIEJE\n\n";system("pause");return (false);};

bool zapis ()
{
	fstream plikdyskowy ;
	plikdyskowy.open ("d:\\wydatki.bin",ios::out|ios::binary);
	if( plikdyskowy.good() == true )
{
	cout<<wskmieszkanie<<endl;int xx=sizeof (mieszkanie)*12;
	cout<<xx<<endl;
	plikdyskowy.write ((char*)wskmieszkanie,(sizeof(mieszkanie)*12));
	plikdyskowy.close();cout<<"ZAPISANO\n\n";system("pause");return (true);
}
	cout<<"NIE ZAPISANO\n\n";system("pause");return (false);
};
bool odczyt ()
{
	fstream plikdyskowy ;
	plikdyskowy.open ("d:\\wydatki.bin",ios::out|ios::binary);
	if( plikdyskowy.good() == true )
{
	plikdyskowy.read ((char*)wskmieszkanie,(sizeof(mieszkanie)*12));
	plikdyskowy.close();cout<<"ODCZYTANO DANE\n\n";system("pause");return (true);
}
	cout<<"BLAD ODCZYTU\n\n";system("pause");return (false);
};



int _tmain(int argc, _TCHAR* argv[])
{
	system("cls");
	unsigned short int miesiac=0;float dana=0;string odp=" ";
	if (plik())
	{if (odczyt()){cout<<"\n\nODCZYTANO DANE\n\n";system("pause");};};
	
	do{
	do{
	system ("cls");
	cout << sizeof (mieszkanie)<<"\n\n";
	cout << "(w)prowadzanie , (s)tatystyki , (k)oniec  ?   ";cin>>odp;cout<<endl;
	} while (odp!="k" & odp!="s" & odp!="w");
	if (odp=="w"){cout << "Miesiac ,ktorego dotyczy wpis ? ";cin >> miesiac ;miesiac--;cout << endl;wprowadzanie(miesiac);};
	if (odp=="s"){statystyki ();};
	} while (odp!="k");
	zapis();
	delete [] wskmieszkanie;
	return 0;
};
0

Oczy roz*ebane. Ubierz to w znaczniki, bo się czytać nie da. W C++ jest serializacja, że można obiekt utrwalać w pliku? Lepiej będzie na bieżąco zapisywać te dane, które potrzebujesz. W ogóle tak tu mieszasz C i C++, że szkoda gadać. Skoro dopiero się uczysz C++, to po jaką cholerę od programowania obiektowego?

0

Cześć, w znaczniki poszło, (moje niedopatrzenie poprzednim razem, przepraszam), Co do mieszania się nie wypowiadam , posiłkuję się literaturą dotyczącą C++ i na podstawie tego piszę program . Z tego co doczytałem w wiki to c++ jako tako nie wspiera sam w sobie serializacji .Wyszedłem z założenia że skoro:

fstream plikdyskowy ;
plikdyskowy.open ("d:\\wydatki.bin",ios::out|ios::binary);
plikdyskowy.write ((char*)wskmieszkanie,(sizeof(mieszkanie)*12));
plikdyskowy.close()

powyższy kod powoduje zapisanie do pliku stanu pamięci z pod adresu wskmieszkanie o długości jaką zajmuje 12 obiektów klasy mieszkanie
to procedura odwrotna powinna dokładnie taki sam blok pamięci wczytać pod aktualny adres umieszczenia tablicy obiektów ??

Więc ponawiam moje pytanie z powyżej - dlaczego w obecnym kodzie nie odczytuje mi poprawnie ,(lub nie zapisuje), tablicy obiektów ? . Pozdrawiam Witek


#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
using namespace std ;

class wodomierz 
{
private:
float stan_licznika ;
public:
wodomierz () {stan_licznika=0;}
~wodomierz () {}
float podajstan () {return (stan_licznika);}
void ustawstan (float stan) {stan_licznika=stan;}
};

class mieszkanie
{
float stawkaciepla ; float stawkazimna ; float kilowat ; float czynsz ; float opllicznik ; float inne1 ; float inne2 ; float inne3 ;
wodomierz cieplalazienka;wodomierz zimnalazienka;wodomierz cieplakuchnia;wodomierz zimnakuchnia;wodomierz licznikpradu;

public:
mieszkanie () {czynsz=390.0;opllicznik=6.50;kilowat=0.53;stawkaciepla=29.31;stawkazimna=11.08;inne1=0;inne2=0;inne3=0;}
~mieszkanie () {}
		
void uczynsz (float Wczynsz) {czynsz=Wczynsz;}
void uoplatelicznikowa (float Wopllicz) {opllicznik=Wopllicz;}
void ustawkaciepla (float Wstan) {stawkaciepla=Wstan;}
void ustawkazimna (float Wstan) {stawkazimna=Wstan;}
void ukilowat (float Wstan) {kilowat=Wstan;}
void uinne1 (float Winne1) {inne1=Winne1;}
void uinne2 (float Winne2) {inne2=Winne2;}
void uinne3 (float Winne3) {inne3=Winne3;}
void ucieplalazienka (float Wstan) {cieplalazienka.ustawstan (Wstan);}
void uzimnalazienka (float Wstan) {zimnalazienka.ustawstan (Wstan);}
void ucieplakuchnia (float Wstan) {cieplakuchnia.ustawstan (Wstan);}
void uzimnakuchnia (float Wstan) {zimnakuchnia.ustawstan (Wstan);}
void ulicznikpradu (float Wstan) {licznikpradu.ustawstan (Wstan);}
float pstawkaciepla (){return(stawkaciepla);}
float pstawkazimna (){return(stawkazimna);}
float pkilowat (){return(kilowat);}
float pczynsz () {return (czynsz);}
float poplatelicznikowa () {return (opllicznik);}
float pinne1 () {return (inne1);}
float pinne2 () {return (inne2);}
float pinne3 () {return (inne3);}
float pcieplalazienka () {return (cieplalazienka.podajstan ());}
float pzimnalazienka () {return (zimnalazienka.podajstan ());}
float pcieplakuchnia () {return (cieplakuchnia.podajstan ());}
float pzimnakuchnia () {return (zimnakuchnia.podajstan ());}
float plicznikpradu () {return (licznikpradu.podajstan ());}
};

mieszkanie * wskmieszkanie = new mieszkanie [12];

void wprowadzanie(short unsigned int miesiac)
{
float dana=0;string odp=" ";
system ("cls");
cout <<"Aktualna stawka czynszu: "<<wskmieszkanie[miesiac].pczynsz()<<endl;
cout <<"Aktualna stawka oplaty licznikowej: "<<wskmieszkanie[miesiac].poplatelicznikowa()<<endl;
cout <<"Aktualna stawka za m3 cieplej wody: "<<wskmieszkanie[miesiac].pstawkaciepla()<<endl;
cout <<"Aktualna stawka za m3 zimnej wody: "<<wskmieszkanie[miesiac].pstawkazimna()<<endl;
cout <<"Aktualna stawka za kilowat:  "<<wskmieszkanie[miesiac].pkilowat()<<endl<<endl<<endl;
cout <<"(1)\tStan cieplej wody kuchnia:  ?  "<<wskmieszkanie[miesiac].pcieplakuchnia()<<endl;
cout <<"(2)\tStan zimnej wody kuchnia:  ?  "<<wskmieszkanie[miesiac].pzimnakuchnia()<<endl;
cout <<"(3)\tStan cieplej wody lazienka:  ?  "<<wskmieszkanie[miesiac].pcieplalazienka()<<endl;
cout <<"(4)\tStan zimnej wody lazienka:  ?  "<<wskmieszkanie[miesiac].pzimnalazienka()<<endl;
cout <<"(5)\tStan licznika pradu:  ?  "<<wskmieszkanie[miesiac].plicznikpradu()<<endl;

cout << "\nCzy bedzie zmiana stawki: ?  \n(c)zynszu\n(o)platy licznikowej\nc(i)eplej\nzi(m)nej\n(k)ilowata\nlicznikow (1,2,3,4,5)\nKo(n)iec  ? ";
cin >> odp;
cout<<endl;
	
for (int x=1;x<=(odp.length());x++)
{
if (odp[x-1]=='n'){break ;};
if (odp[x-1]=='c'){cout << "\nPodaj nowa stawke czynszu :  ";cin >> dana ;wskmieszkanie[miesiac].uczynsz(dana);};
if (odp[x-1]=='o'){cout << "\nPodaj nowa stawke oplaty licznikowej ?   ";cin >> dana;wskmieszkanie[miesiac].uoplatelicznikowa(dana);};
if (odp[x-1]=='i'){cout << "\nPodaj nowa stawke za m3 cieplej wody ?   ";cin >> dana;wskmieszkanie[miesiac].ustawkaciepla(dana);};
if (odp[x-1]=='m'){cout << "\nPodaj nowa stawke za m3 zimnej wody ?   ";cin >> dana;wskmieszkanie[miesiac].ustawkazimna(dana);};
if (odp[x-1]=='k'){cout << "\nPodaj nowa stawka za kilowat ?   ";cin >> dana;wskmieszkanie[miesiac].ukilowat(dana);};
if (odp[x-1]=='1'){cout << "\nPodaj kuchnia ciepla :   ?  ";cin>>dana;wskmieszkanie[miesiac].ucieplakuchnia(dana);};
if (odp[x-1]=='2'){cout << "\nPodaj kuchnia zimna :   ?  ";cin>>dana;wskmieszkanie[miesiac].uzimnakuchnia(dana);};
if (odp[x-1]=='3'){cout << "\nPodaj lazienka ciepla :   ?  ";cin>>dana;wskmieszkanie[miesiac].ucieplalazienka(dana);};
if (odp[x-1]=='4'){cout << "\nPodaj lazienka zimna :   ?  ";cin>>dana;wskmieszkanie[miesiac].uzimnalazienka(dana);};
if (odp[x-1]=='5'){cout << "\nPodaj licznik pradu :   ?  ";cin>>dana;wskmieszkanie[miesiac].ulicznikpradu(dana);};
};

return ;
};

bool plik ()
{
fstream plikdyskowy ;
plikdyskowy.open ("d:\\wydatki.bin",ios::in|ios::binary);
if( plikdyskowy.good() == true ) {plikdyskowy.close();cout<<"PLIK ISTNIEJE\n\n";system("pause");return (true);};
cout<<"PLIK NIE ISTNIEJE\n\n";system("pause");return (false);
};

bool zapis ()
{
fstream plikdyskowy ;
plikdyskowy.open ("d:\\wydatki.bin",ios::out|ios::binary);
if( plikdyskowy.good() == true )
{
cout<<wskmieszkanie<<endl;int xx=sizeof (mieszkanie)*12;
cout<<xx<<endl;
plikdyskowy.write ((char*)wskmieszkanie,(sizeof(mieszkanie)*12));
plikdyskowy.close();cout<<"ZAPISANO\n\n";system("pause");return (true);
};
cout<<"NIE ZAPISANO\n\n";system("pause");return (false);
};
bool odczyt ()
{
fstream plikdyskowy ;
plikdyskowy.open ("d:\\wydatki.bin",ios::out|ios::binary);
if( plikdyskowy.good() == true )
{
plikdyskowy.read ((char*)wskmieszkanie,(sizeof(mieszkanie)*12));
plikdyskowy.close();cout<<"ODCZYTANO DANE\n\n";system("pause");return (true);
}
cout<<"BLAD ODCZYTU\n\n";system("pause");return (false);
};

int _tmain(int argc, _TCHAR* argv[])
{
	system("cls");
	unsigned short int miesiac=0;float dana=0;string odp=" ";
	if (plik())
	{if (odczyt()){cout<<"\n\nODCZYTANO DANE\n\n";system("pause");};};
	
	do{
	do{
	system ("cls");
	cout << sizeof (mieszkanie)<<"\n\n";
	cout << "(w)prowadzanie , (s)tatystyki , (k)oniec  ?   ";cin>>odp;cout<<endl;
	} while (odp!="k" & odp!="s" & odp!="w");
	if (odp=="w"){cout << "Miesiac ,ktorego dotyczy wpis ? ";cin >> miesiac ;miesiac--;cout << endl;wprowadzanie(miesiac);};
	if (odp=="s"){statystyki ();};
	} while (odp!="k");
	zapis();
	delete [] wskmieszkanie;
	return 0;
};
0

żeby dobrze się czytało:
#po każdym średniku ma być koniec wiersza, bo inaczej się dostaje oczopląsu
#Każdy nawias otwierający zwiększa wcięcie następnej linii, a zamykający przywraca wcięcie następnej linii do poprzedniego stanu przed odpowiadającym nawiasem otwierającym.
#jeśli masz problem tylko z zapisem i odczytem, to pokazuj tylko fragmenty za to odpowiedzialne oraz deklarację używanych w tym kontekście klas. reszta tylko zaciemnia problem i zniechęca do odpowiedzi.
#jeśli koniecznie chcesz zmieszać całość, to dawaj linka do zip-a z kodem.

0

Ja tylko dodam, że tutaj Plik Binarny Rev b. dobrze opisał jak się powinno serializować.

0
MarekR22 napisał(a)

żeby dobrze się czytało:
#po każdym średniku ma być koniec wiersza, bo inaczej się dostaje oczopląsu
#Każdy nawias otwierający zwiększa wcięcie następnej linii, a zamykający przywraca wcięcie następnej linii do poprzedniego stanu przed odpowiadającym nawiasem otwierającym.
#jeśli masz problem tylko z zapisem i odczytem, to pokazuj tylko fragmenty za to odpowiedzialne oraz deklarację używanych w tym kontekście klas. reszta tylko zaciemnia problem i zniechęca do odpowiedzi.
#jeśli koniecznie chcesz zmieszać całość, to dawaj linka do zip-a z kodem.

ok. poprawię się .To był mój pierwszy wpis związany z tym forum . Myślę że nie ostatni :).pozdro.V.

0
yurai napisał(a)

Ja tylko dodam, że tutaj Plik Binarny Rev b. dobrze opisał jak się powinno serializować.

ok. zabieram się za czytanie . dzięki . pozdro. V.

0

Uniwersalnie będzie w Boost:
http://www.boost.org/doc/libs/1_48_0/libs/serialization/doc/index.html

Trochę mniej uniwersalnie, za to wygodniej w JSON, np:
http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx

0

Temat rozwiązałem rozwijając to co było - o dziwo zadziałało ;) - dzięki za wszystkie podpowiedzi . Poniżej moje rozwiązanie

class wodomierz 
{
        private:
	      float stan_licznika ;
        public:
	      wodomierz () {stan_licznika=0;}
	      ~wodomierz () {}
	      float podajstan () {return (stan_licznika);}
	      void ustawstan (float stan) {stan_licznika=stan;}
};
class mieszkanie 
{
              float stawkaciepla ; float stawkazimna ; float kilowat ; float czynsz ;
              float opllicznik ; float inne1 ; float inne2 ; float inne3 ;
              wodomierz cieplalazienka;wodomierz zimnalazienka;
              wodomierz cieplakuchnia;wodomierz zimnakuchnia;wodomierz licznikpradu;

        public:
	mieszkanie () {czynsz=390.0;opllicznik=6.50;kilowat=0.53;stawkaciepla=29.31;stawkazimna=11.08;inne1=0;inne2=0;inne3=0;}
	~mieszkanie () {}
		
	// ---- metody -------//
};

mieszkanie * wskmieszkanie = new mieszkanie [12];

// - procedura zapisu

bool zapis ()
{
	fstream plikdyskowy ;
	plikdyskowy.open ("d:\\wydatki.bin",ios::out|ios::binary);
	if( plikdyskowy.good() == true )
               {for (int x=0;x<12;x++)
	              {
	                plikdyskowy.write ((char*)(&wskmieszkanie[x]),sizeof(wskmieszkanie[x]));
	              };
               plikdyskowy.close();return (true);
               }
cout<<"NIE ZAPISANO\n\n";system("pause");return (false);
};

// - procedura odczytu

 bool odczyt ()
{
	fstream plikdyskowy ;
	plikdyskowy.open ("d:\\wydatki.bin",ios::in|ios::binary);
	if( plikdyskowy.good() == true )
            { for (int x=0;x<12;x++)
	            {
	            plikdyskowy.read ((char*)(&wskmieszkanie[x]),sizeof(wskmieszkanie[x]));
	            }
	    plikdyskowy.close();cout<<"ODCZYTANO DANE\n\n";system("pause");return (true);
            }
cout<<"BLAD ODCZYTU\n\n";system("pause");return (false);
};
 

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