fread i fwrite tablica struktur

fread i fwrite tablica struktur
0

Witam,

Piszę prosty program, żeby sobie przećwiczyć funkcje fread i fwrite. No i napotkałem problem.

Program imituje bazę danych (na strukturach). Dodaje, usuwa itp. No i jest zapis z i do pliku.
I tu pojawia się problem. 2 dni nad tym siędze i już mnie nerwy zżerają.

Struktura:

Kopiuj
struct entry{
		string sName;
		string sSurname;
		unsigned int uiAge;
		bool bEmpty;
}; 

Wywołanie funkcji zapisu i odczytu :

Kopiuj
vSaveDb(person, sPlik);
vOpenDb(person, sPlik);
 

Person to tablica struktur struct entry person[10]

Ciała funkcji:
Zapis:

Kopiuj
void vSaveDb(entry *e, char *sPlik){
	FILE *plik;
	plik=fopen(sPlik,"w");
	if(plik!=NULL){
		size_t save=fwrite(e,sizeof(e),MAX_ENTRIES,plik);
		cout<<save<<endl;
		fclose(plik); 
	}
	else cout<<"Error open file"<<endl;
}

Odczyt (ma być zapisane do struktury person, której wskaźnik przekazuje do funkcji):

Kopiuj
void vOpenDb(entry *e, char *sPlik){
	FILE *pFile = fopen(sPlik, "rb");
	if(pFile)
    {
                size_t result;
		cout<<result<<endl;
		result = fread (&e,sizeof(e),MAX_ENTRIES,pFile);
        fclose(pFile);
	}
    else cout<<"Error open file"<<endl;
}
 

Wiem, że coś robię źle z samą strukturą ale nie mogę znaleźć błędu.

KR
fread (&e,sizeof(e),MAX_ENTRIES,pFile); <-- tutaj wywal & przed e
KR
plik=fopen(sPlik,"w"); <-- w zamień na wb
KR
sizeof(e) zamień na sizeof(entry)
mto9
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 10 lat
  • Postów:380
0

W strukturze używasz stringów dla tego występuje ten błąd... i również szukałem pomocy na tym forum z tego co zrozumiałem wynikało że błąd ten jest spowodowany tym że string to tak naprawdę wskaźnik do pewnej pamięci która zawiera dany napis.. Podczas zapisu do pliku zlicza się wagę struktury entry.. Stringi zliczane są jako wskaźniki (czyli bodajże 4 bajty) a nie odwzorują prawdziwej wagi napisu.. jeśli bardzo chcesz mieć stringi w tej strukturze musisz napisać własne funkcje do odczytu zapisu.. Tutaj jak ja sobie poradziłem z tym problemem: (tak wiem wiem można szybciej za pomocą szablonów ale nie doszedłem jeszcze do tego rozdziału więc radze sobie jak mogę ;D ):
KLASA:

Kopiuj
class c_user
{
    public:

        void Zapisz() const;
        void Wczytaj();

    private:

        std::string nick;
        std::string e_mail;
        std::string haslo;
        std::string smtp;
        short int port;
};

Funkcja Zapisz()

Kopiuj
void c_user::Zapisz() const
{
    std::ofstream fout("c_user",std::ios::binary);
    if (!fout) f_error_savefile();

    char * wpis;
    int waga=nick.length()+1;
    wpis=new char [waga];
    strcpy (wpis, nick.c_str ());

    fout.write((char*) & waga,sizeof(waga));
    fout.write(wpis ,waga);

    delete [] wpis;
    waga=e_mail.length()+1;
    wpis=new char[waga];
    strcpy (wpis, e_mail.c_str());

    fout.write((char*)&waga,sizeof(waga));
    fout.write(wpis ,waga);

    delete [] wpis;
    waga=haslo.length()+1;
    wpis=new char[waga];
    strcpy(wpis,haslo.c_str());

    fout.write((char*)&waga,sizeof(waga));
    fout.write(wpis,waga);

    delete [] wpis;
    waga=smtp.length()+1;
    wpis=new char[waga];
    strcpy(wpis,smtp.c_str());

    fout.write((char*)&waga,sizeof(waga));
    fout.write(wpis,waga);

    delete [] wpis;
    wpis=0;

    fout.write((char*) &port,sizeof (port));

    fout.close();
}

Funkcja Wczytaj():

Kopiuj
oid c_user::Wczytaj()
{
    std::ifstream fin("c_user",std::ios::binary);
    if (!fin) f_error_loadfile();

    char * wczyt;
    int waga;

    fin.read((char*) &waga,sizeof(waga));
    wczyt=new char[waga];
    fin.read(wczyt, waga);
    nick=wczyt;
    delete [] wczyt;

    fin.read((char*)&waga,sizeof(waga));
    wczyt=new char[waga];
    fin.read(wczyt,waga);
    e_mail=wczyt;
    delete [] wczyt;

    fin.read((char*)&waga,sizeof(waga));
    wczyt=new char[waga];
    fin.read(wczyt,waga);
    haslo=wczyt;
    delete [] wczyt;

    fin.read((char*)&waga,sizeof(waga));
    wczyt=new char[waga];
    fin.read(wczyt,waga);
    smtp=wczyt;
    delete [] wczyt;

    fin.read((char*) &port,sizeof (port));

    fin.close();
}

Zapraszam jeszcze tutaj: http://4programmers.net/Forum/Newbie/185070-zapisodczyt_obiektu_klasy_doz_pliku_binarnego-dziwny_blad

edytowany 1x, ostatnio: mto9
0

Dzięki wielkie!
Tyle czasu, a tu tylko o string chodzi.
Już zmieniłem na char i wszytko działa jak należy. Dzięki jeszcze raz.

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.