mrwszystko Temat założony przez niniejszego użytkownika |
Wczytywanie struktury za pomocą fread wyrzuca błąd aplikacji » 2013-05-13 10:28:17 Witam, Piszę program, w którym potrzebne mi jest zapisywanie i wczytywanie struktury do pliku. Próbuję to zrobić za pomocą funkcji fwrite oraz fread. Zapisywanie wygląda na poprawnie działające ale gdy chcę odczytać zapisana strukturę funkcją fread to aplikacja wywala okienko z błędem "Wystąpił problem z aplikacją Project1.exe i zostanie ona zamknięta". Oto kod na którym testowałem to zapisywanie i odczytywanie: #include <stdio.h> #include <stdlib.h> #include <iostream>
using namespace std;
struct data { int dzien; int mies; int rok; };
struct towar { string nazwa; string haslo; data data_przyjecia; } tow;
int main( int argc, char * argv[] ) { tow.nazwa = "Test"; tow.haslo = "test2"; tow.data_przyjecia.dzien = 12; tow.data_przyjecia.mies = 02; tow.data_przyjecia.rok = 1999; FILE * fs; fs = fopen( "plik.txt", "w" ); fwrite( & tow, sizeof( tow ), 1, fs ); fclose( fs ); FILE * fr; fs = fopen( "plik.txt", "r" ); fread( & tow, sizeof( tow ), 1, fr ); fclose( fr ); cout << tow.nazwa << endl; cout << tow.haslo << endl; cout << tow.data_przyjecia.dzien << endl; cout << tow.data_przyjecia.mies << endl; cout << tow.data_przyjecia.rok << endl; system( "PAUSE" ); return EXIT_SUCCESS; }
Jestem początkujący także jeśli coś prostego spieprzyłem to nie gnojcie mnie za bardzo :P |
|
akwes |
» 2013-05-13 10:49:10 Problemem może być std::string. Zamiast std::string użyj czegoś co ma stały rozmiar. Na przykład char nazwa[ 50 ]; . std::string w zależności od implementacji może oferować różne "sztuczki" przechowywania swojej wartości. sizeof(std::string) jest zależne od implementacji i czasami może zwracać stałą wartość dla każdego obiektu std::string, co skutkuje barkiem możliwości poprawnego zapisania i odczytania tego "bajt po bajcie". |
|
Monika90 |
» 2013-05-13 10:55:43 Co zwraca sizeof(std::string), to faktycznie zależy od implementacji. Ale pewne jest, że zawsze zwraca stałą znaną już w czasie kompilacji, która oczywiście nie zalezy od długości stringa. To samo dotyczy struktury, która zawiera std::string. Ogólnie, nie można używać fread, fwrite, memset, memcpy, itp. do obiektów które nie są PODami, czyli takich które mają nietrywialny konstruktor kopiujący czy operator przypisania, f. wirtualne i inne rzeczy nie znane w C.
Poza tym, jest i inny błąd, jak używasz binarnego I/O to powinieneś otwierać pliki w trybie binarnym. Warto też sprawdzać czy pliki udało się otworzyć. |
|
mrwszystko Temat założony przez niniejszego użytkownika |
» 2013-05-13 11:28:44 Dzięki za informacje :) W takim razie jaka inna funkcja będzie najlepsza do zapisywania struktur, tych bardziej skomplikowanych? I jeszcze jedno pytanie, czy dozwolone jest zapisywanie struktury, która zawiera jeszcze inna strukturę w sobie? |
|
Monika90 |
» 2013-05-13 12:03:55 Najlepiej to chyba zdefiniować funkcje, które zapisują i wczytują obiekty różnych typów i użyć tych funkcji do implementacji funkcji odczytujacych/zapisujacych bardziej złożone obiekty. Przykład (pomijający istotne szczegóły takie jak obsługa błędów) const char delimiter = '\n';
void save( std::FILE * file, const std::string & str ) { assert( str.find( delimiter ) == std::string::npos ); std::fwrite( str.data(), str.size(), 1, file ); std::fputc( delimiter, file ); }
void load( std::FILE * file, std::string & str ) { str.clear(); int ch; while( ch = std::fgetc( file ), ch != delimiter && ch != EOF ) str.push_back( ch ); }
void save( std::FILE * file, const data & d ) { std::fwrite( & d, sizeof d, 1, file ); }
void load( std::FILE * file, data & d ) { std::fread( & d, sizeof d, 1, file ); }
void save( std::FILE * file, const towar & tow ) { save( file, tow.nazwa ); save( file, tow.haslo ); save( file, tow.data_przyjecia ); }
void load( std::FILE * file, towar & tow ) { load( file, tow.nazwa ); laod( file, tow.haslo ); load( file, tow.data_przyjecia ); }
Chyba jest dobrze, ale używaj tego na własną odpowiedzialność. |
|
mrwszystko Temat założony przez niniejszego użytkownika |
» 2013-05-13 14:11:29 Ok. Już chyba sobie poradzę. Wielkie dzięki wszystkim :) |
|
« 1 » |