#include #include // for width() #include // for ifstream/ofstream #include // for tolower #include "apstring.h" #include "apvector.h" #include "search.h" // ********************************** // author: Owen Astrachan // // see people.cpp for comments, this version sorts // using different criteria and the functions in sortall.h // (as in people2.cpp), but this version also supports // iteration by client code over all the elements in a collection // // ********************************** struct Person { apstring myFirst,myLast; apstring mySchool; apstring myGender; int myNumber; Person(); Person(const apstring & first, const apstring & last, const apstring & school, const apstring & gender, int number); void Print(ostream & out) const; }; ostream& operator << (ostream & out, const Person & p) //postcondition: p printed to out, out returned { p.Print(out); return out; } // ************************************ // implement Person // *********************************** Person::Person() // postcondition: initialized with default values { } Person::Person(const apstring & first, const apstring & last, const apstring & school, const apstring & gender, int number) : myFirst(first), myLast(last), mySchool(school), myGender(gender), myNumber(number) { // initialized using initializer list } void Person::Print(ostream & out) const // postcondition: person printed to stream out { out << setw(20) << myFirst + " " + myLast << setw(15) << mySchool << char(toupper(myGender[0])) << " " << myNumber; } // ********************************** // Collection of people // ********************************** struct NumberCompare { int compare(const Person & lhs, const Person & rhs) { if (lhs.myNumber == rhs.myNumber) return 0; if (lhs.myNumber < rhs.myNumber) return -1; return 1; } }; struct NameMatch { NameMatch(const apstring & key) : myKey(key) { } bool IsMatch(const Person & p) const { return p.myLast.find(myKey) != npos; } apstring myKey; }; class Collection { public: Collection(); // accessor or const functions void Print(ostream & out) const; // print collection void First() const; bool HasMore() const; void Next() const; const Person& Current() const; // mutator functions void Add(const Person & p); // add p to collection void Clear(); // remove everyone private: apvector myList; // the people in collection int myCount; // # people in collection mutable int myIndex; // for iterating }; template void Search(const Collection & coll, Collection & match, const Predicate & pred) { for(coll.First(); coll.HasMore(); coll.Next()) { if (pred.IsMatch(coll.Current())) { match.Add(coll.Current()); } } } Collection::Collection() : myList(10), myCount(0), myIndex(0) /// postcondition: collection initialized with zero people { } void Collection::First() const { myIndex = 0; } bool Collection::HasMore() const { return myIndex < myCount; } void Collection::Next() const { myIndex++; } const Person& Collection::Current() const { return myList[myIndex]; } void Collection::Print(ostream & out) const // postcondition: all elements of collection are printed { int k; for(k=0;k < myCount; k++) { out << myList[k] << endl; } cout << "------ " << myCount << " total people" << endl; } void Collection::Add(const Person & p) // postcondition: p added to collection { if (myCount >= myList.length()) { myList.resize(myList.length()*2); } myList[myCount] = p; myCount++; } void Collection::Clear() { myCount = 0; } void PrintNamesOnly(const Collection & coll) { for(coll.First(); coll.HasMore(); coll.Next()) { cout << coll.Current().myFirst << "\t" << coll.Current().myLast << endl; } } int main() { apstring filename = "c:\\ets\\workshop\\98subgroup"; ifstream input; input.open(filename.c_str()); if (! input.good()) { cerr << "could not open " << filename << endl; return(1); } Collection group,matchGroup; apstring name,gender,school,number; int spaceIndex; while (getline(input,name) && getline(input,gender) && getline(input,school) && getline(input,number)) { spaceIndex = name.find(' '); Person p(name.substr(0,spaceIndex), name.substr(spaceIndex+1, name.length()), school, gender, atoi(number.c_str())); group.Add(p); } PrintNamesOnly(group); // group.Print(cout); while (true) { cout << endl << "search for: (return to quit) "; getline(cin,name); if (name == "") break; NameMatch matcher(name); Search(group,matchGroup,matcher); cout << endl << "matches follow" << endl << endl; matchGroup.Print(cout); } cout << endl << "searching over" << endl; return 0; }