// Workshop 9 - Smart Pointers // w9.cpp #include <iostream> #include <iomanip> #include "Element.h" #include "List.h" const int FWC = 5; const int FWD = 12; const int FWP = 8; w9::List<w9::Product> merge(const w9::List<w9::Description>& desc,const w9::List<w9::Price>& price) { w9::List<w9::Product> priceList1; w9::List<w9::Product> priceList; int size1 = desc.size(), size2 = price.size(); for (int i = 0; i < size1; ++i) for (int j = 0; j < size2; ++j) { if (desc[i].code == price[j].code) { //w9::Product *temp = new w9::Product; std::auto_ptr<w9::Product> temp(new w9::Product); temp->desc = desc[i].desc; temp->price = price[j].price; temp->validate(price[j].price); if (temp->price < 0) return priceList1; priceList += temp; } } return priceList; } int main(int argc, char** argv) { std::cout << "\nCommand Line : "; for (int i = 0; i < argc; i++) { std::cout << argv[i] << ' '; } std::cout << std::endl; if (argc != 3) { std::cerr << "\n***Incorrect number of arguments***\n"; return 1; } try { w9::List<w9::Description> desc(argv[1]); std::cout << std::endl; std::cout << std::setw(FWC) << "Code" <<std::setw(FWD) << "Description" << std::endl; std::cout << desc << std::endl; w9::List<w9::Price> price(argv[2]); std::cout << std::endl; std::cout << std::setw(FWC) << "Code" <<std::setw(FWP) << "Price" << std::endl; std::cout << price << std::endl; w9::List<w9::Product> priceList = merge(desc, price); std::cout << std::endl; std::cout << std::setw(FWD) << "Description" <<std::setw(FWP) << "Price" << std::endl; std::cout << priceList << std::endl; } catch (const std::string& msg) { std::cerr << msg << std::endl; } catch (const char* msg) { std::cerr << msg << std::endl; } catch (int) { std::cout << "*** Negative prices are invalid ***" << std::endl; } std::cout << "\nPress any key to continue ... "; std::cin.get(); }
// Element.h #include <iostream> #include <iomanip> #include <string> #include <fstream> extern const int FWC; extern const int FWD; extern const int FWP; namespace w9 { struct Description { unsigned code; std::string desc; bool load(std::ifstream& f) { f >> code >> desc; return f.good(); } void display(std::ostream& os) const { os << std::setw(FWC) << code << std::setw(FWD)<< desc << std::endl; } }; struct Price { unsigned code; double price; bool load(std::ifstream& f) { f >> code >> price; return f.good(); } void display(std::ostream& os) const { os << std::setw(FWC) << code << std::setw(FWP)<< price << std::endl; } }; struct Product { std::string desc; double price; Product() {} Product(const std::string& str, double p) : desc(str), price(p) {} void display(std::ostream& os) const { os << std::setw(FWD) << desc << std::setw(FWP)<< price << std::endl; } void validate(double p) { if (p < 0) throw 1; } }; }
// List.h #include <iostream> #include <iomanip> #include <vector> #include <string> #include <fstream> namespace w9 { template <typename T> class List { std::vector<T> list; public: List() { } List(const char* fn) { std::ifstream file(fn); if (!file) throw std::string("*** Failed to open file ") +std::string(fn) + std::string(" ***"); while (file) { T e; if (e.load(file)) list.push_back(*new T(e)); } } size_t size() const { return list.size(); } const T& operator[](size_t i) const { return list[i]; } void operator+=(std::auto_ptr<T> p) { list.push_back(*p); } void display(std::ostream& os) const { os << std::fixed << std::setprecision(2); for (auto &e:list) e.display(os); } }; template<typename T> std::ostream& operator<<(std::ostream& os, const List<T>& l) { l.display(os); return os; } }
//Prices.dat 4067 0.99 4068 0.67 4039 1.99 4056 2.49
//Descriptions.dat 4662 tomatoes 4039 cucumbers 4056 brocolli 4067 lemons 4068 oranges
//BadPrices.dat 4067 0.99 4068 0.67 4039 1.99 4056 -2.49