#include #include #include #include using namespace std; const int asize = 512; class Film { public: Film(); void store_title( const char[ ] = "" ); void store_director( const char[ ] = "" ); void store_time( int = 0 ); void store_quality( int = 0 ); virtual void output(); virtual void input( ifstream& ); static bool read_input( const char[ ], Film*[ ], int ); private: char title[ asize ]; char director[ asize ]; int time; // in minutes int quality; // 0 (bad) to 4 (tops) }; Film::Film() { store_title(); store_director(); store_time(); store_quality(); } void Film::store_title( const char t[ ] ) { strcpy( title, t ); } void Film::store_director( const char d[ ] ) { strcpy( director, d ); } void Film::store_time( int t ) { time = t; } void Film::store_quality( int q ) { quality = q; } // Reads title, director, time, and quality. void Film::input( ifstream& fin ) { const unsigned n = 200; char inbuff[ n ]; fin.getline( inbuff, n ); store_title( inbuff ); fin.getline( inbuff, n ); store_director( inbuff ); fin.getline( inbuff, n ); store_time( atoi( inbuff ) ); fin.getline( inbuff, n ); store_quality( atoi( inbuff ) ); } // Writes title, director, time, and quality. void Film::output() { cout << "Title: " << title << endl; cout << "Director: " << director << endl; cout << "Time: " << time << " mins" << endl; cout << "Quality: "; for ( int i = 0; i < quality; i++ ) cout << '*'; cout << endl; } class DirectorCut : public Film { public: DirectorCut(); void store_rev_time( int = 0 ); void store_changes( const char [ ] = "" ); virtual void output(); virtual void input( ifstream& ); private: int rev_time; char changes[ asize ]; }; DirectorCut::DirectorCut() { store_rev_time(); store_changes(); } void DirectorCut::store_rev_time( int t ) { rev_time = t; } void DirectorCut::store_changes( const char s[ ] ) { strcpy( changes, s ); } // Reads revised time and changes. void DirectorCut::input( ifstream& fin ) { Film::input( fin ); const unsigned n = 200; char inbuff[ n ]; fin.getline( inbuff, n ); store_rev_time( atoi( inbuff ) ); fin.getline( inbuff, n ); store_changes( inbuff ); } // Writes revised time and changes. void DirectorCut::output() { Film::output(); cout << "Revised time: " << rev_time << endl; cout << "Changes: " << changes << endl; } class ForeignFilm : public Film { public: ForeignFilm(); void store_language( const char[ ] = "" ); virtual void output(); virtual void input( ifstream& ); private: char language[ asize ]; }; ForeignFilm::ForeignFilm() { store_language(); } void ForeignFilm::store_language( const char l[ ] ) { strcpy( language, l ); } // Reads language. void ForeignFilm::input( ifstream& fin ) { Film::input( fin ); const unsigned n = 200; char inbuff[ n ]; fin.getline( inbuff, n ); store_language( inbuff ); } // Writes language. void ForeignFilm::output() { Film::output(); cout << "Language: " << language << endl; } // class method: Film::read_input // Reads data from an input file, dynamically creating the // appropriate Film object for each record group. For // instance, a ForeignFilm object is dynamically created if // the data represent a foreign film rather than a regular // film or a director's cut. Pointers to dynamically created // objects are stored in the array films of size n. Returns // true to signal success and false to signal failure. bool Film::read_input( const char file[ ], Film* films[ ], int n ) { const int buffSize = 200; char inbuff[ buffSize ]; ifstream fin( file ); if ( !fin ) // opened successfully? return false; // if not, return false // Read until end-of-file. Records fall into // groups. 1st record in each group is a string // that represents a Film type: // "Film", "ForeignFilm", "DirectorCut", etc. // After reading type record, dynamically create // an object of the type (e.g., a ForeignFilm object), // place it in the array films, and invoke its // input method. int next = 0; while ( fin.getline( inbuff, buffSize ) && next < n ) { if ( strcmp( inbuff, "Film" ) == 0 ) films[ next ] = new Film(); // regular film else if ( strcmp( inbuff, "ForeignFilm" ) == 0 ) films[ next ] = new ForeignFilm(); // foreign film else if ( strcmp( inbuff, "DirectorCut" ) == 0 ) films[ next ] = new DirectorCut(); // director's cut else //**** error condition: unrecognized film type continue; films[ next++ ]->input( fin ); // polymorphic method } fin.close(); return true; }