carlosmay Temat założony przez niniejszego użytkownika |
[C++] Odczyt z pliku binarnego obiektów klasy ze składowymi std::string » 2015-10-24 11:47:37 Program dla obiektów struktury działa prawidłowo, natomiast dla obiektów klasy zgłasza wyjątek. #include <iostream> #include <fstream> #include <conio.h> #include <string> #include <iomanip> using namespace std;
struct Stoo { int st_lp; string st_name; };
class Foo { string m_name; double m_weight; public: Foo() : m_name( "" ) , m_weight( 0 ) { } Foo( const string & s, double wt ) : m_name( s ) , m_weight( wt ) { } Foo( const Foo & f ) : m_name( f.m_name ) , m_weight( f.m_weight ) { }; ~Foo() { }; friend ostream & operator <<( ostream & os, Foo & f ) { return os << setw( 15 ) << left << f.m_name << setw( 10 ) << fixed << left << setprecision( 2 ) << f.m_weight << endl; } };
int main() { Stoo st[ 2 ] = { { 1, "kolo" }, { 2, "jozef" } }; Foo foo[ 2 ] = { { "Earth", 1.00 }, { "Jupiter", 317.83 } }; fstream fout, fin; fout.open( "Users.dat", ios::out | ios::binary ); if( fout.is_open() ) { fout.write(( char * ) & st, sizeof( st ) ); } else { cerr << "Open file: error!" << endl; _getch(); return EXIT_FAILURE; } fout.close(); fout.open( "Planets2.dat", ios::out | ios::binary ); if( fout.is_open() ) { fout.write(( char * ) & foo, sizeof( foo ) ); } else { cerr << "Open file: error!" << endl; _getch(); return EXIT_FAILURE; } fout.close(); fin.open( "Users.dat", ios::in | ios::binary ); if( fin.is_open() ) { Stoo temp[ 2 ]; for( int i = 0; i < 2; i++ ) { fin.read(( char * ) & temp[ i ], sizeof( temp[ i ] ) ); cout << temp[ i ].st_lp << " " << temp[ i ].st_name << endl; } } else { cerr << "Open file: error!" << endl; _getch(); return EXIT_FAILURE; } fin.close(); fin.open( "Planets2.dat", ios::in | ios::binary ); if( fin.is_open() ) { Foo ftemp[ 2 ]; for( int i = 0; i < 2; i++ ) { fin.read(( char * ) & ftemp, sizeof( ftemp ) ); cout << ftemp[ i ]; } } else { cerr << "Open file: error!" << endl; _getch(); return EXIT_FAILURE; } fin.close(); _getch(); return EXIT_SUCCESS; }
Program wypisuje na ekran dane ze struktury i klasy prawidłowo 1 kolo 2 jozef Earth 1.00 Jupiter 317.83
i przy kończeniu programu zgłasza wyjątek Zgłoszono wyjątek w lokalizacji 0x000B8CA0 w ConsoleApplication1.exe: 0xC0000005: Naruszenie zasad dostępu podczas zapisywania w lokalizacji 0xDDDDDDDD. Dlaczego tylko dla klasy zgłasza wyjątek? Czy można całe obiekty klasy ze składowymi string zapisywać do pliku? Jeśli tak to jak? Czy jednak trzeba pisać przeciązenie '>>' do odczytu danych z pliku? |
|
Monika90 |
» 2015-10-24 12:01:11 Nie można tak zapisywać, a tym bardziej odczytywać obiektów std::string i nie ma znaczenia czy są w klasie czy w strukturze, bo struktura to też klasa. |
|
pekfos |
» 2015-10-24 12:20:20 Temat tak powtarzający się i nudny, że doczekał się FAQ w formie artykułu.. Zapis binarnyto nawet proste, dodam sobie jeszcze stringa.. *wybuch atomowy*. Już nawet nie będę próbować liczyć, ile tematów na forum do tego można sprowadzić |
|
|
carlosmay Temat założony przez niniejszego użytkownika |
» 2015-10-24 16:08:05 #include <iostream> #include <fstream> #include <conio.h> #include <string> #include <iomanip> using namespace std;
class Foo { int m_position; string m_name; float m_weight; public: Foo() : m_name( "" ) , m_weight( 0 ) , m_position( 0 ) { } Foo( const string & nm, float wt, int pos ) : m_name( nm ) , m_weight( wt ) , m_position( pos ) { } Foo( const Foo & f ) : m_name( f.m_name ) , m_weight( f.m_weight ) , m_position( f.m_position ) { } ~Foo() { } friend ostream & operator <<( ostream & os, const Foo & f ) { return os << setw( 3 ) << left << f.m_position << setw( 15 ) << left << f.m_name << setw( 10 ) << right << fixed << setprecision( 3 ) << f.m_weight << endl; } void save(); void load(); };
int main() { Foo f1( "Earth", 1, 3 ); cout << f1; f1.save(); Foo f2; f2.load(); cout << f2; _getch(); return EXIT_SUCCESS; }
void Foo::save() { fstream fout( "Planets.dat", ios::binary | ios::out ); if( !fout.is_open() ) return; fout.write(( char * ) & m_position, sizeof( int ) ); fout.write( m_name.c_str(), m_name.size() + 1 ); fout.write(( char * ) & m_weight, sizeof( float ) ); }
void Foo::load() { fstream fin( "Planets.dat", ios::in | ios::binary ); if( !fin.is_open() ) return; fin.read(( char * ) & m_position, sizeof( int ) ); getline( fin, m_name, '\0' ); fin.read(( char * ) & m_weight, sizeof( float ) ); }
Teraz działa. Program dla obiektów struktury działa prawidłowo |
jednak nie działał prawidłowo. Temat tak powtarzający się i nudny, że doczekał się FAQ w formie artykułu. |
dla kogoś z dużym doświadczeniem pewnie tak. Googlowałem temat, przeczytałem kilka z tego serwisu, ale nie było jednoznacznej odpowiedzi, a na ten link akurat nie trafiłem. Dzięki :) |
|
« 1 » |