#include #include #include #include #include using namespace std; //*** file names and miscellaneous globals const char inFile[ ] = "stockData.dat"; const unsigned MaxSymbol = 4; const char Unknown[ ] = "????"; //*** objects generated from input records class Stock { public: Stock() { strcpy( symbol, Unknown ); open = close = gainLoss = volume = 0; } Stock( const char s[ ], // symbol double o, // opening price double c, // closing price unsigned long v ) { // volume traded strncpy( symbol, s, MaxSymbol ); symbol[ MaxSymbol ] = '\0'; open = o; close = c; volume = v; gainLoss = ( close - open ) / open; } const char* getSymbol() const { return symbol; } double getOpen() const { return open; } double getClose() const { return close; } unsigned long getVolume() const { return volume; } double getGainLoss() const { return gainLoss; } private: char symbol[ MaxSymbol + 1 ]; double open; // opening price double close; // closing price double gainLoss; // gain or loss fraction unsigned long volume; // shares traded }; //*** Sort comparison: gains in descending order template< class T > struct winCmp { bool operator()( T& t1, T& t2 ) const { return t1.getGainLoss() > t2.getGainLoss(); } }; //*** Sort comparison: volume in descending order template< class T > struct volCmp { bool operator()( T& t1, T& t2 ) const { return t1.getVolume() > t2.getVolume(); } }; //*** invoked by function objects to do output void output( bool volFlag, const char name[ ], const char openLabel[ ], double open, const char closeLabel[ ], double close, const char gainLabel[ ], double gain, const char volLabel[ ], unsigned long vol ) { cout << "*** " << name << endl; if ( volFlag ) // if true, volume comes first cout << '\t' << volLabel << vol << endl; cout << '\t' << gainLabel << gain << endl << '\t' << openLabel << open << endl << '\t' << closeLabel << close << endl; if ( !volFlag ) // if false, volume comes last cout << '\t' << volLabel << vol << endl; } //*** Write Stocks sorted by gain-loss to standard output. template< class T > struct winPr { void operator()( Stock& s ) { output( false, s.getSymbol(), "Opening Price: ", s.getOpen(), "Closing Price: ", s.getClose(), "% Changed: ", s.getGainLoss() * 100, "Volume: ", s.getVolume() ); } }; //*** Write Stocks sorted by volume to standard output. template< class T > struct volPr { void operator()( Stock& s ) { output( true, s.getSymbol(), "Opening Price: ", s.getOpen(), "Closing Price: ", s.getClose(), "% Changed: ", s.getGainLoss() * 100, "Volume: ", s.getVolume() ); } }; void herald( const char[ ] ); void input( deque< Stock >& ); int main() { deque< Stock > stocks; //*** Input stocks and separate into vectors for // winners, losers, and break-evens. input( stocks ); //*** Sort winners in descending order and output. herald( "Gainers in descending order: " ); sort( stocks.begin(), stocks.end(), winCmp< Stock >() ); for_each( stocks.begin(), stocks.end(), winPr< Stock >() ); //*** Output losers in ascending order. herald( "Losers in ascending order: " ); for_each( stocks.rbegin(), stocks.rend(), winPr< Stock >() ); //*** Sort volume in descending order and output herald( "Volume in descending order: " ); sort( stocks.begin(), stocks.end(), volCmp< Stock >() ); for_each( stocks.begin(), stocks.end(), volPr< Stock >() ); return 0; } void input( deque< Stock >& d ) { char s[ MaxSymbol + 1 ]; double o, c, v; ifstream input( inFile ); //*** Read data until end-of-file, // creating a Stock object per input record while ( input >> s >> o >> c >> v ) d.insert( d.end(), Stock( s, o, c, v ) ); input.close(); } void herald( const char s[ ] ) { cout << endl << "******* " << s << endl; }