// CIS22B, Fall 2020: Assignment 6 solution #include #include #include #include #include using namespace std; class NFL_Team { private: string name; string conference; string division; unsigned short wins; unsigned short losses; unsigned short ties; public: string getName() const { return name; } string getConference() const { return conference; } string getDivision() const { return division; } unsigned short getWins() const { return wins; } unsigned short getLosses() const { return losses; } unsigned short getTies() const { return ties; } float percent() const; void print() const; void createTeam(const string& team, const string& conf, const string& div); void incrementWins() { wins++; } void incrementLosses() { losses++; } void incrementTies() { ties++; } float sortKey(); void swap(NFL_Team& b); }; void getNFL_Teams(const string& filename, NFL_Team* teams); void processGames(const string& filename, NFL_Team* teams); int getTeamIndexInString(const string& String, NFL_Team* teams); int getScorefromTeamScoreString(const string& teamScoreString); void calculateTeamPct(NFL_Team* teams); void printStandings(NFL_Team* teams); void printTeams(NFL_Team* teams); void sortForStandings(NFL_Team a[]); void rtrim(string&); // remove trailing spaces from string const int NumTeams = 32; const string TeamsFile = "c:/temp/teams.txt"; const string ScoresFile = "c:/temp/scores.prn"; int main() { NFL_Team teams[NumTeams]; getNFL_Teams(TeamsFile, teams); //printTeams(teams); // output for verification only processGames(ScoresFile, teams); //printTeams(teams); // output for verification only sortForStandings(teams); //printTeams(teams); // output for verification only printStandings(teams); } void getNFL_Teams(const string& filename, NFL_Team* teams) { ifstream fin(filename); string buffer; if (!fin) { cerr << "Unable to open team file " << filename << endl; exit(1); } int i = 0; string conference; string division; size_t pos; while (getline(fin,buffer)) { // skip a blank line if (buffer.size()<8) continue; // remove \r for Unix/Linux/Mac execution if (buffer.back()=='\r') buffer.pop_back(); if (buffer.find("Conference") != string::npos) { pos = buffer.find(' '); conference = buffer.substr(0,pos+1); continue; } else if (buffer.find("FC") != string::npos) { pos = buffer.find(' '); division = buffer.substr(pos+1); continue; } else { teams[i].createTeam(buffer,conference,division); i++; } } if (!fin) fin.clear(); fin.close(); } void NFL_Team::createTeam(const string& tm, const string& conf, const string& div) { name = tm; conference = conf; division = div; wins = losses = ties = 0; } void processGames(const string& filename, NFL_Team* teams) { string buffer; string team1, team2; string teamscore1, teamscore2; // string to hold team name and score int score1, score2; int team1Index, team2Index; ifstream fin(filename); if (!fin) { cerr << "Unable to open games file " << filename << endl; exit(2); } while (getline(fin,buffer)) { if (!fin) break; if (buffer.back()=='\r') buffer.pop_back(); if (buffer.substr(1,4) == "Date") continue; team1 = buffer.substr(7,25); team2 = buffer.substr(35,25); rtrim(team1); rtrim(team2); score1 = stoi(buffer.substr(72,2)); score2 = stoi(buffer.substr(77,2)); team1Index = getTeamIndexInString(team1, teams); team2Index = getTeamIndexInString(team2, teams); // Make sure teams are valid if (team1Index < 0 || team2Index < 0) { cerr << "Unable to process scores record: " << teamscore1 << ", " << teamscore2 << endl; exit(2); } if (score1 > score2) { teams[team1Index].incrementWins(); teams[team2Index].incrementLosses(); } else if (score1 < score2) { teams[team2Index].incrementWins(); teams[team1Index].incrementLosses(); } else { teams[team2Index].incrementTies(); teams[team1Index].incrementTies(); } } fin.close(); } int getTeamIndexInString(const string& String, NFL_Team* teams) { for (int i = 0; i < NumTeams; i++) { if (String.find(teams[i].getName()) != string::npos) return i; } return -1; } int getScorefromTeamScoreString(const string& teamScoreString) { size_t scorePos = teamScoreString.rfind(' ') + 1; return stoi(teamScoreString.substr(scorePos)); } float NFL_Team::percent() const { return (wins + .5 * ties)/ (wins + losses + ties); } void NFL_Team::print() const { cout << left << setw(24) << name << right << setw(3) << wins << setw(6) << losses << setw(6) << ties << setw(8) << percent() << endl; } void printStandings(NFL_Team* teams) { string div; cout << setprecision(3) << fixed; for (int i = 0; i < NumTeams; i++) { if (i%(NumTeams/2) == 0) cout << endl << teams[i].getConference() << " Football Conference" << endl; if (teams[i].getDivision() != div) { cout << endl << left << setw(6) << teams[i].getDivision() << "Division W L T Pct" << endl; div = teams[i].getDivision(); } teams[i].print(); } } void printTeams(NFL_Team* teams) { cout << setprecision(3) << fixed << left; for (int i = 0; i < NumTeams; i++) { cout << setw(9) << teams[i].getConference() << setw(6) << teams[i].getDivision() << setw(10) << teams[i].sortKey() << " "; teams[i].print(); } cout << endl; } float NFL_Team::sortKey() { char firstCharOfConference = conference[0]; char firstCharOfDivision = division[0]; int conferenceAsAnInt = static_cast(firstCharOfConference); int divisionAsAnInt = static_cast(firstCharOfDivision); float pctInReverseOrder = 1 - percent(); float key = 100 * conferenceAsAnInt + divisionAsAnInt + pctInReverseOrder; return key; } void sortForStandings(NFL_Team a[]) { int minIndex; for (int i = 0; i < NumTeams - 1; i++) { minIndex = i; for (int j = i + 1; j < NumTeams; j++) { if (a[j].sortKey() < a[minIndex].sortKey()) { minIndex = j; } } if (minIndex != i) { a[i].swap(a[minIndex]); } } } void NFL_Team::swap(NFL_Team& b) { NFL_Team temp = b; b = *this; *this = temp; } void rtrim(string& str) // remove trailing spaces from string { for (size_t i = str.size()-1; i > 10; i--) { if (isspace(str[i])) { str.pop_back(); } else return; } }