#include #include #include #include #include using namespace std; //*** file names and miscellaneous globals const string inFile = "stockData.dat"; const string Unknown = "????"; //*** objects generated from input records class Stock { public: Stock() { symbol = Unknown; open = close = gainLoss = volume = 0; } Stock( const string& s, // symbol double o, // opening price double c, // closing price unsigned long v ) { // volume traded symbol = s; open = o; close = c; volume = v; gainLoss = ( close - open ) / open; } const string& 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: string symbol; 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 struct winCmp { bool operator()( const Stock& s1, const Stock& s2 ) const { return s1.getGainLoss() > s2.getGainLoss(); } }; //*** Sort comparison: volume in descending order struct volCmp { bool operator()( const Stock& s1, const Stock& s2 ) const { return s1.getVolume() > s2.getVolume(); } }; //*** invoked by function objects to do output void output( bool volFlag, const string& 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. struct winPr { void operator()( const Stock& s ) const { 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. struct volPr { void operator()( const Stock& s ) const { 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() ); for_each( stocks.begin(), stocks.end(), winPr() ); //*** Output losers in ascending order. herald( "Losers in ascending order: " ); for_each( stocks.rbegin(), stocks.rend(), winPr() ); //*** Sort volume in descending order and output herald( "Volume in descending order: " ); sort( stocks.begin(), stocks.end(), volCmp() ); for_each( stocks.begin(), stocks.end(), volPr() ); return 0; } void input( deque< Stock >& d ) { string s; double o, c, v; ifstream input( inFile.c_str() ); //*** 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; }