zapis obiektu do pliku...

0

Dlaczego to mi caly czas zapisuje smieci do pliku tekstowego zamiast danyc ktore podaje ?
Bylbym wdzieczny za mala pomoc...

static char _Fname[32] = "ksiazka.txt"; /zmienna globalna/

class osoba
{
char *nazw;
char *imie;
int wiek;
public:
int nr;
void wyswietl();
int wprowadz();
osoba(char *imie, char *nazw, int wiek); //konstruktor z parametrami 1
~osoba(); //desktruktor

};

osoba::osoba(char *imie, char *nazw, int wiek) //konstruktor z parametrami 1
{
cout<<endl<<"Uruchamiam konstruktor z parametrami (imie, nazwisko, wiek)."<<endl<<endl;

this->nazw=strdup(" ");//zarezerwowanie pamieci
this->imie=strdup(" ");
strcpy(this->imie,imie);
strcpy(this->nazw,nazw);
this->wiek=wiek;
cout<<"Utworzylem osobe:"<<endl;
cout<<"Imie: "<<this->imie<<endl;
cout<<"Nazwisko: "<<this->nazw<<endl;
cout<<"Wiek: "<<this->wiek<<endl<<endl;
};

osoba::~osoba()//destruktor
{

cout<<"Wywoluje destruktor"<<endl<<endl;
cout<<"Usuniety obiekt osoba:"<<endl;
cout<<"Imie: "<<imie<<endl<<"Nazwisko: "<<nazw<<endl<<"wiek: "<<wiek<<endl<<endl;
};

void menu()
{
cout<<"1 - Wprowadz"<<endl;
cout<<"2 - Wyswietl na ekran"<<endl;
cout<<"Esc - Wyjscie"<<endl;
};

void menu_wpr()
{
clrscr();
/*cout<<"Ilosc osob w bazie (pobierana ze skladowej statycznej): "<<osoba::IleObiektow()<<endl<<endl;
ZLICZYC ELEMENTY W PLIKU BINARNYM */
cout<<"1 - Uzyj konstruktora z paramentrem nr 1 (imie,nazw,wiek)"<<endl;
cout<<"ESC - Powrot do poprzedniego menu"<<endl;
cout<<"______________________________________________________________"<<endl;
};

int wpr(osoba **osoby)
{
clrscr();
menu_wpr();
int k=0;
while (k!=27)
{
k=getch();
clrscr();
switch (k)
case '1' : {
cout<<"Konstruktor z parametrem 1 (imie, nazwisko, wiek)"<<endl<<endl;
char *imie=strdup(" ");
char nazw=strdup(" ");
int wiek=0;
cout<<"Podaj imie: ";
cin>>imie;
cout<<"Podaj nazwisko: ";
cin>>nazw;
cout<<"Podaj wiek: ";
cin>>wiek;
osoba dane=new osoba(imie, nazw, wiek);
osoby[1]=dane;
FILE
f = fopen(_Fname, "wt");
if(!f) return 0;
fwrite((char
)&dane, sizeof(osoba), 1, f);
fclose(f);
free(imie);
free(nazw);
cout<<endl<<"Wcisnij ENTER...";
getchar();
};
}

return 1;
};

void main()
{
osoba osoby=(osoba) malloc (sizeof(osoba*));
clrscr();
int key=0;
while (key!=27)
{
clrscr();
menu();
key=getch();
switch (key)
{
case '1' : wpr(osoby);break;
//case '2' : wysw(osoby); break;
}
};
delete osoby;
free(osoby);
};

0

Tak się nie zapisuje obiektów - to nie struktury (

struct

) ;). Poczytaj o serializacji.

0

aaaha dobrze wiedziec ;)
Dzieki za info postaram sie znaleŹĆ cos na ten temat i poczytac...
ale przyznam ze pierwszy raz sie spotykam z takim pojeciem jak : serializacja

0

A czy da sie w jakis inny sposob zapisac do pliku obiekt ,niekoniecznie poprzez serializacje ??

0

A dlaczego inaczej??? przecież to nie jest aż tak skomplikowane ;) Zauważ, że w klasie osoba masz wskaźniki (

char *nazw

, char *imie

) i zapisując ją w ten sposób: <code class="cpp"> fwrite((char*)&dane, sizeof(osoba), 1, f);

zapisujesz adresy ale nie text na który wskazują.

0

a jakbym tam nie mial wskaznikow to dalo by rade w ten sposob zapisac? :)
Ciezko znaleŹĆ cos na temat serializacji w c++ :(

0

a jakbym tam nie mial wskaznikow to dalo by rade w ten sposob zapisac

Jak już pisałem, obiektów w ten sposób nie zapisuje się (vtable, wskaźniki itd.).

Ciezko znaleŹĆ cos na temat serializacji w c++

Słabo szukasz ;)

Dodaj do swojej klasy funkcję (nietestowana):

void osoba::Store(FILE *stream)
{
 // zapisujemy długość textu + 1
 int tmp=strlen(nazw)+1; 
 fwrite((char*)&tmp,sizeof(int), 1, stream); 
 // zapisujemy text
 fwrite(nazw,tmp, 1, stream); 

 tmp=strlen(imie)+1;
 fwrite((char*)&tmp,sizeof(int), 1, stream); 
 fwrite(imie, tmp, 1, stream); 
 
 fwrite((char*)&wiek, sizeof(int), 1, stream); 
}

Funkcję odczytującą sam sobie napisz ;)

0

OK Sprobuje,a do jakiego pliku mi zapisze obiekt do tekstowego czy do binarnego?

0

Niestety po wprowadzeniu do klasy tej funkcji :

void osoba::Store(FILE stream)
{
// zapisujemy długość textu + 1
int tmp=strlen(nazw)+1;
fwrite((char
)&tmp,sizeof(int), 1, stream);
// zapisujemy text
fwrite(nazw,tmp, 1, stream);

tmp=strlen(imie)+1;
fwrite((char*)&tmp,sizeof(int), 1, stream);
fwrite(imie, tmp, 1, stream);

fwrite((char*)&wiek, sizeof(int), 1, stream);
}

w sekcji Public dalem to :

void Store(FILE *stream);

Oraz po zastosowaniu tej funkcji w ten oto sposob :

osoba dane=new osoba(imie, nazw, wiek);
osoby[1]=dane;
FILE
f = fopen(_Fname, "wt");
if(!f) return 0;
dane->Store(f);

gdzie _Fname to:

static char _Fname[32] = "ksiazka.txt"; /zmienna globalna/

przy kompilacji wyrzuca blad :

Error E2285 tel2.cpp 59: Could not find a match for 'fwrite(int,unsigned int,int
,FILE *)' in function osoba::Store(FILE *)

Nie wiem jaka jest tego przyczyna niestety :/

0

Coś jest nie tak z pierwszym parametrem ale nie widzę nigdzie błędu :/ Załączyłeś

#include <stdio.h>

???

0
5il3nt napisał(a)

fwrite((char*)&wiek, sizeof(int), 1, stream);

W tej linijce byl blad...Jest OK
Poza tym ze moj plik txt do ktorego zapisuje po wprowadzeniu danych:Piotr Nowak wiek:33 wyglada tak :

Nowak Piotr ,

:/

0
0x666 napisał(a)

Coś jest nie tak z pierwszym parametrem ale nie widzę nigdzie błędu :/ Załączyłeś

#include <stdio.h>

???

edytor chyba zmienil mi ta linijke i dlatego byl blad...

0

Poza tym ze moj plik txt do ktorego zapisuje po wprowadzeniu danych:Piotr Nowak wiek:33 wyglada tak :

Nowak Piotr ,

Czyli wyszło tak jak trzeba ;) Było mówić, że chodzi ci o postać tekstową.

0
0x666 napisał(a)

Poza tym ze moj plik txt do ktorego zapisuje po wprowadzeniu danych:Piotr Nowak wiek:33 wyglada tak :

Nowak Piotr ,

Czyli wyszło tak jak trzeba ;) Było mówić, że chodzi ci o postać tekstową.

:)W sumie to chodzi mi o taka i taka,chcialbym aby normalnie zapisywal do binarnego ale takze aby byla mozliwosc zapisania zawartosci pliku binarnego do pliku tekstowego.
Na poczatek chcialem zapisac do tekstowego zeby latwiej sprawdzic czy sie poprawnie zapisuje.
A jaka byla by roznica jesli chodzi o tekstowa postac a binarna ?

0

Po pierwsze. Piszesz w C++, więc zamiast

char[]

wykorzystaj string

 - masz wycieki pamięci ;) Po drugie. Do odczytu/zapisu w postaci tekstowej możesz przeciążyć operatory <code class="cpp"><< >>

.

#include <string>
#include <ostream>
#include <istream>

using namespace std;

class osoba
{
  private:
    string nazw;
    string imie;
    int wiek;
 public:
    int nr;
    void wyswietl();
    int wprowadz();
    osoba(string imie,string nazw, int wiek);
    ~osoba();

   ofstream& operator >> (ofstream& os)
   {
     os<<nazw<<endl<<imie<<endl<<wiek<<endl;
     return os;
   }

   ifstream& operator << (ifstream& is)
   {
     is>>nazw>>imie>>wiek;
     return is;
   }
};

Wywołanie:

osoba person("A","B",0x666);

/* zapis */
ofstream ofile("file.txt");
person>>ofile;

/* odczyt */
ifstream ifile("file.txt");
person<<ifile;

A jaka byla by roznica jesli chodzi o tekstowa postac a binarna ?

Binarnie:

Nowak Piotr ,

Tekstowo:

Nowak
Piotr
44

PS. kody oczywiście nietestowane :P

0
0x666 napisał(a)

Wywołanie:

osoba person("A","B",0x666);

Nie rozumiem tej linijki...Co to jest A i B ?

0
5il3nt napisał(a)
0x666 napisał(a)

Wywołanie:

osoba person("A","B",0x666);

Nie rozumiem tej linijki...Co to jest A i B ?

:D A to przykładowe imię, B to nazwisko, a 0x666 to wiek.

0

hehe :) Tak tez przypuszczalem;)

Zaraz to przetestuje....

Generalnie to mialo by tak wygladac ze zapisuje sobie obiekt do pliku binarnego pozniej wyswietlam zawartosc tego pliku na ekran albo zapisuje do pliku tekstowego.

0

Error E2094 tel3.cpp 26: 'operator<<' not implemented in type 'ofstream' for arg
uments of type 'char *' in function osoba::operator >>(ofstream &)
Error E2094 tel3.cpp 31: 'operator>>' not implemented in type 'ifstream' for arg
uments of type 'char *' in function osoba::operator <<(ifstream &)
Error E2450 tel3.cpp 127: Undefined structure 'ofstream' in function wpr(osoba *
*)
Error E2034 tel3.cpp 127: Cannot convert 'char *' to 'ofstream' in function wpr(
osoba * *)
Error E2450 tel3.cpp 127: Undefined structure 'ofstream' in function wpr(osoba *
*)
Error E2450 tel3.cpp 127: Undefined structure 'ofstream' in function wpr(osoba *
*)

taka seria bledow mi sie teraz zaczela pojawiac przy kompilacji :(

0

A może jakieś szczegóły w postaci kodu???

0

Kod zamieszcze jutro...
Jedno pytanie,jak zastosowac stringi w celu zniwelowania wyciekow pamieci ?Wystarczy ze zmienie w tych miejscach kodu co mi podales na STRING...bo zdaje mi sie ze musialbym porobic wieksze przerobki w calym programie aby przejsc na stringi.

0
5il3nt napisał(a)

Jedno pytanie,jak zastosowac stringi w celu zniwelowania wyciekow pamieci ?

string'i są prostsze w obsłudze - nie musisz się martwić o odpowiędnią ilość pamięci dla textu itd. - co w znacznym stopniu uchroni cię przed popełnianiem błędów związanych z alokacją, zwalnianiem i przekraczaniem zakresu pamięci. I tak w konstruktorze masz:

this->nazw=strdup("                     "); //<--- alokujesz pamięć
this->imie=strdup("                     ");  //<--- alokujesz pamięć
strcpy(this->imie,imie);
strcpy(this->nazw,nazw);

a w destruktorze nie zwalniasz tej pamięci funkcją

free

. Ogólnie to dziwnie wykorzystałeś funkcję strdup

 - jedynie pełni rolę funkcji <code class="cpp">alloc

, a przecież możnaby zrobić tak:

this->nazw=strdup(nazw);
this->imie=strdup(imie);

Tak poprawniej i bezpieczniej ;)

5il3nt napisał(a)

Wystarczy ze zmienie w tych miejscach kodu co mi podales na STRING...bo zdaje mi sie ze musialbym porobic wieksze przerobki w calym programie aby przejsc na stringi.

No nie do końca. Tu już nie będą potrzebne funkcję

strcpy

, strdup

 itd. Kopiowanie stringów wygląda jak zwykłe przypisanie np. dla int'ów. Poszukaj w necie informacji o string'ach.
0

Czy przeciążenie operatorów << >> moge wykorzystac tylko do odczytu/zapisu w postaci tekstowej czy takze binarnej ?

Nie chce juz kombinowac tylko zrobie tak jak ma byc finalnie czyli zapis imion i nazwisk do pliku binarnego i pozniej ewentualny odczyt z binarnego i wyswietlenie na ekran lub zapisanie calego binarnego do pliku tekstowego.

0

Czy przeciążenie operatorów << >> moge wykorzystac tylko do odczytu/zapisu w postaci tekstowej czy takze binarnej ?

Można... ale zrobiłbym to inaczej. Operatory

<< >>

przeciążyłbym dla strumieni sformatowanych (czyli wy/we textowe), a do odczytu/zapisu binarnego użyłbym zwykłych funkcji/metod.

class osoba
{
  private:
   
...

  public:

...
   /* cout<<osoba <---textowo na ekran */
   friend ostream& operator << (ostream& os,osoba &obj)
   {
     os<<"Nazwisko: "<<obj.nazw<<endl;
     os<<"Imie: "<<obj.imie<<endl;
     os<<"Wiek: "<<obj.wiek<<endl;
     return os;
   }

   /* ofstream<<osoba <---textowo do pliku */
   friend ofstream& operator << (ofstream& os,osoba &obj)
   {
     os<<obj.nazw<<endl<<obj.imie<<endl<<obj.wiek<<endl;
     return os;
   }

   /* ifstream>>osoba <---textowo z pliku */
   friend ifstream& operator >> (ifstream& is,osoba &obj)
   {
     is>>obj.nazw>>obj.imie>>obj.wiek;
     return is;
   }

   void BinarySave(ofstream&);
   void BinaryLoad(ifstream&);
};
0

Ten kod powyzej wyglada mi dosc skomplikowanie...nie bardzo wiem jak go zastosowac :/
Dopiero zaczynam zabawe z programowaniem w C++
Zrobilem zapis do pliku w ten sposob:

static char _Fname[32] = "ksiazka.bin"; /zmienna globalna/

class osoba
{
char *nazw;
char *imie;
int wiek;
public:
int nr;
int Store();
friend void Read();
osoba(char *imie,char *nazw, int wiek); //konstruktor z parametrami 1
~osoba(); //desktruktor

};

.......

int osoba::Store()
{

ofstream fout(_Fname,ios::app);
if (!fout)
{
cout << "nie mozna otworzyc pliku" <<_Fname ;
return 0;
}
fout.write((char*)&nazw,sizeof nazw);
fout.write((char*)&imie,sizeof imie);
fout.write((char*)&wiek,sizeof wiek);

fout.close();
}

I wyglada ze jest ok...problem pojawil sie przy odczycie :

     void Read()
     {
         osoba p_Data;
         fstream binary_file(_Fname,ios::binary|ios::in);
         binary_file.read(reinterpret_cast<char *>(&p_Data),sizeof(osoba));
         binary_file.close();

         cout<<p_Data.wiek<<endl;


     }

Error E2285 projekt.cpp 70: Could not find a match for 'osoba::osoba()' in funct
ion Read()

Prosze o jakas podpowiedz jesli ktos wie co nalezaloby zrobic aby bylo OK.

0
class osoba
{
   char nazw[50];
   char imie[50];
   int wiek;
public:
   void Store(char *filename);
   void Read(char *filename);
   void Print();
   osoba(char *_imie, char *_nazw, int _wiek);
   ~osoba();
};

osoba::osoba(char *_imie, char *_nazw, int _wiek)
{
   strcpy(imie, _imie);
   strcpy(nazw, _nazw);
   wiek = _wiek;
};

osoba::~osoba()
{
}

void osoba::Store(char *filename)
{
   ofstream fout(filename, ios::out | ios::trunc);
   if(!fout)
   {
      cout << "nie mozna otworzyc pliku \"" << filename << "\"" << endl;
      return;
   }
   fout << nazw << endl << imie << endl << wiek;
   fout.close();
   cout << "zapisano osobe do pliku \"" << filename << "\"" << endl;
}

void osoba::Read(char *filename)
{
   ifstream fin(filename, ios::in);
   if(!fin)
   {
      cout << "nie mozna otworzyc pliku \"" << filename << "\"" << endl;
      return;
   }
   fin >> nazw;
   fin >> imie;
   fin >> wiek;
   fin.close();
   cout << "odczytano plik \"" << filename << "\"" << endl;
}

void osoba::Print()
{
   std::cout << imie << " " << nazw << " lat " << wiek << endl;
}

int main(int argc, char* argv[])
{
   osoba *os = new osoba("janusz", "januszewicz", 32);
   os->Print();
   os->Store(_Fname);
   delete os;

   os = new osoba("tomek", "tomczynski", 21);
   os->Print();
   os->Read(_Fname);
   os->Print();

   return 0;
}
0
5il3nt napisał(a)

Ten kod powyzej wyglada mi dosc skomplikowanie...nie bardzo wiem jak go zastosowac

Przecież w komentarzach napisałem jak i do czego służą ;)

I wyglada ze jest ok...problem pojawil sie przy odczycie :

Pojawił się problem bo to jest odczyt binarny więc musisz wiedzieć co i w jakiej ilości odczytywać - przyjrzyj się mojej funkcji zapisującej. Z resztą już pisałem, że tak (jak zrobiłeś) nie powinien wygłądać zapis/odczyt obiektów.

Error E2285 projekt.cpp 70: Could not find a match for 'osoba::osoba()' in function Read()

brakuje domyślnego konstruktora w twojej klasie więc taka deklaracja nie przejdzie:

 osoba p_Data;

ale taka już tak:

 osoba p_Data("janusz", "januszewicz", 32);

wniosek: dodaj domyślny konstruktor.

0
adf88 napisał(a)


int main(int argc, char* argv[])
{


}

Co to jest : int argc oraz char*argv[] ????

Zrobilem bez tych argumentow i niby dziala...w koncu :)
Zaczal dobrze odczytywac i zapisywac...chyba :P jutro dalsza faza testow....

0

MSDN

0

5il3nt: aby zgłebić swój problem dowiedz sie coś o wskaźnikach, konwersjach typów (i funkcjach atoi, itoa...) i strumieniach.

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