Code:
#include <string> // for use of string
#include <fstream> //for file handling
#include <iostream> // for file handling
#include <cstdlib>
#include <iomanip> //for the setprecision used further below
using namespace std;
struct MasterData //struct created named 'MasterData' to hold one line from master file
{
string playerId,
firstName,
lastName,
division,
teamName;
int appearances,
atBats,
singles,
doubles,
triples,
homeRuns,
sacFly,
walks,
hitByPitch;
double battingAvg,
OBP,
sluggingPercent;
};
struct MasterUpdate // struct created for the Update of the master file
{
string recordType;
MasterData record;
};
istream &operator>>(istream& in, MasterData& d) //Overloads the input and output
{ //Overloads the ">>" operator
string value; //Temporary variable to hold the string form before actual conversion to string
int i;
getline(in, d.playerId, ',');
getline(in, d.firstName, ',');
getline(in, d.lastName, ',');
getline(in, d.division, ',');
getline(in, d.teamName, ',');
getline(in, value, ',');
d.appearances = stoi(value); //stoi converts string to int and then stores it in MasterData
getline(in, value, ',');
d.atBats = stoi(value);
getline(in, value, ',');
d.singles = stoi(value);
getline(in, value, ',');
d.doubles = stoi(value);
getline(in, value, ',');
d.triples = stoi(value);
getline(in, value, ',');
d.homeRuns = stoi(value);
getline(in, value, ',');
d.sacFly = stoi(value);
getline(in, value, ',');
d.walks = stoi(value);
getline(in, value, ',');
d.hitByPitch = stoi(value);
getline(in, value, ',');
d.battingAvg = stod(value); // stod converts string to double and then stores it in MasterData
getline(in, value, ',');
d.OBP = stod(value);
getline(in, value, '\n');
d.sluggingPercent = stod(value);
return in;
}
ostream &operator<<(ostream& out, MasterData d)
{
//Overloads the "<<" operator
out << setw(11) << d.playerId << "|";
out << setw(15) << d.firstName << "|";
out << setw(15) << d.lastName << "|";
out << setw(15) << d.division << "|";
out << setw(15) << d.teamName << "|";
out << setw(15) << d.appearances << "|";
out << setw(10) << d.atBats << "|";
out << setw(10) << d.singles << "|";
out << setw(10) << d.doubles << "|";
out << setw(10) << d.triples << "|";
out << setw(10) << d.homeRuns << "|";
out << setw(10) << d.sacFly << "|";
out << setw(10) << d.walks << "|";
out << setw(15) << d.hitByPitch << "|";
out << setprecision(3) << fixed; //setprecision to allow 3 decimal places for calculated values (batting avg,OBP, slug%)
out << setw(15) << d.battingAvg << "|";
out << setw(15) << d.OBP << "|";
out << setw(15) << d.sluggingPercent << "|";
out << "\n";
return out;
}
istream &operator>>(istream& in, MasterUpdate& u) //Overload operators for MasterUpdate
{
//Overloads the ">>" operator (opposite of the one above)
getline(in, u.recordType, ',');
in >> u.record;
return in;
}
// Function Prototypes
void swap(MasterData stats[], int x, int y);
void sortByBattingAvg(MasterData stats[], int length);
void sortByDivThenBattingAvg(MasterData stats[], int length);
void sortByTeamThenDiv(MasterData stats[], int length);
void printTop20Batters(ostream& out, MasterData stats[], int length);
void printTop10PlayersbyDivision(ostream& out, MasterData stats[], int length);
void printOffensiveStatsbyTeam(ostream& out, MasterData stats[], int length);
void printNewMaster(ostream& out, MasterData stats[], int length);
void printRecordCSV(ostream& out, MasterData d);
void printHeaders(ostream& out);
void lineA(ostream& out);
void lineB(ostream& out);
int main()
{
ifstream inFile;
inFile.open("Master_Data.csv");
MasterData current;
MasterData stats[500];
int length = 0;
while (!inFile.eof())
{
inFile >> current;
stats[length] = current;
length++;
}
inFile.close();
//Update array for 2014 stats then print out the updated master file
MasterUpdate update;
ifstream inleagueData("2014_League_Stats.csv");
string value;
//Remove Headers
for (int i = 0; i < 17; i++)
getline(inleagueData, value, ',');
getline(inleagueData, value, '\n');
//Make updates
while (!inleagueData.eof())
{
inleagueData >> update;
switch (update.recordType[0])
{
case 'D': //Delete player that did not return to league
for (int i = 0; i < length; i++)
if (update.record.playerId == stats[i].playerId)
{
swap(stats, i, length - 1);
length--;
}
break;
case 'N': //Add new player that is entering the league
stats[length] = update.record;
length++;
break;
case 'R': //Update stats for player returning to league
int position;
for (int i = 0; i < length; i++)
if (update.record.playerId == stats[i].playerId)
position = i;
//Update record based on new stats
stats[position].teamName = update.record.teamName;
stats[position].division = update.record.division;
stats[position].appearances += update.record.appearances;
stats[position].atBats += update.record.atBats;
stats[position].singles += update.record.singles;
stats[position].doubles += update.record.doubles;
stats[position].triples += update.record.triples;
stats[position].homeRuns += update.record.homeRuns;
stats[position].sacFly += update.record.sacFly;
stats[position].walks += update.record.walks;
stats[position].hitByPitch += update.record.hitByPitch;
//Update hits based on new stats
double hits = 0;
hits += stats[position].singles;
hits += stats[position].doubles;
hits += stats[position].triples;
hits += stats[position].homeRuns;
//Update total bases based on the updated hits
double totalBases = 0;
totalBases += stats[position].singles;
totalBases += stats[position].doubles * 2;
totalBases += stats[position].triples * 3;
totalBases += stats[position].homeRuns * 4;
//Update calculated fields for batting average, OBP, and slugging percent
stats[position].OBP = ((hits + stats[position].walks + stats[position].hitByPitch)
/ stats[position].appearances);
stats[position].sluggingPercent = (totalBases / stats[position].atBats);
break;
}
}
//Display the updated master file
ofstream outNewMaster("2014_League_Stats.csv");
printNewMaster(outNewMaster, stats, length);
outNewMaster.close();
//Processing and Output 1 - Top 20 Batters Report
sortByBattingAvg(stats, length);
ofstream top20("Top 20 Batters.txt");
printTop20Batters(top20, stats, length);
top20.close();
//Processing and Output 2 - Top 10 Batters by Division Report
sortByDivThenBattingAvg(stats, length);
ofstream outTop10("Top 10 Players by Division Report.txt");
printTop10PlayersbyDivision(outTop10, stats, length);
outTop10.close();
//Processing and Output 3 - Offensive Stats by Team Report
sortByTeamThenDiv(stats, length);
ofstream outTeamStats("Offensive Stats by Team.txt");
printOffensiveStatsbyTeam(outTeamStats, stats, length);
outTeamStats.close();
}
// Function Definitions
void swap(MasterData stats[], int x, int y) //sort (x and y for positions)
{
MasterData temp = stats[x];
stats[x] = stats[y];
stats[y] = temp;
}
void sortByBattingAvg(MasterData stats[], int length)
{
//select sort
for (int holdPos = 0; holdPos < length - 1; holdPos++) //Position Holder Loop
{
int maxPos = holdPos; //maxPos is recreated for each iteration of Position Holder Loop
for (int valueFindPos = holdPos + 1; valueFindPos < length; valueFindPos++) //Value Finder Loop
{
if (stats[valueFindPos].battingAvg > stats[maxPos].battingAvg) //Sort
maxPos = valueFindPos;
else if (stats[valueFindPos].battingAvg == stats[maxPos].battingAvg && stats[valueFindPos].sluggingPercent > stats[maxPos].sluggingPercent)
maxPos = valueFindPos;
}
swap(stats, holdPos, maxPos); //Swaps biggest value foudn to holdPos (held position)
}
}
void sortByDivThenBattingAvg(MasterData stats[], int length) // Very similar (same logic) as above sort
{
for (int i = 0; i < length - 1; i++)
{
int maxIndex = i;
for (int p = i + 1; p < length; p++)
{
//Sort Logic
if (stats[p].division > stats[maxIndex].division)
maxIndex = p;
else if (stats[p].division == stats[maxIndex].division)
if (stats[p].battingAvg > stats[maxIndex].battingAvg)
maxIndex = p;
}
swap(stats, i, maxIndex);
}
}
void sortByTeamThenDiv(MasterData stats[], int length)
{
for (int i = 0; i < length - 1; i++)
{
int maxPos = i;
for (int p = i + 1; p < length; p++)
{
//Sort Logic
if (stats[p].teamName > stats[maxPos].teamName)
maxPos = p;
else if (stats[p].teamName == stats[maxPos].teamName)
if (stats[p].division > stats[maxPos].division)
maxPos = p;
else if (stats[p].division == stats[maxPos].division)
if (stats[p].battingAvg > stats[maxPos].battingAvg)
maxPos = p;
}
swap(stats, i, maxPos);
}
}
//Prints and Print Helpers
void printTop20Batters(ostream& out, MasterData stats[], int length)
{
printHeaders(out);
for (int i = 0; i < 20; i++)
out << stats[i];
lineA(out);
}
void printTop10PlayersbyDivision(ostream& out, MasterData stats[], int length)
{
int counter = 0;
string currentDivision = stats[0].division;
printHeaders(out); //Prints Headers on top of report
for (int i = 0; i < length; i++)
{
if (stats[i].division == currentDivision && counter < 10)
{
out << stats[i];
counter++;
}
else if (stats[i].division != currentDivision)
{
lineA(out);
out << stats[i];
counter = 1;
currentDivision = stats[i].division;
}
}
lineA(out);
}
void printOffensiveStatsbyTeam(ostream& out, MasterData stats[], int length)
{
int counter = 0;
string currentTeam = stats[0].teamName;
string currentDivision = stats[0].division;
printHeaders(out);
for (int i = 0; i < length; i++)
{
if (stats[i].teamName == currentTeam)
{
if (stats[i].division != currentDivision)
{
lineB(out);
currentDivision = stats[i].division;
}
out << stats[i];
counter++;
}
else
{
lineA(out);
out << stats[i];
counter = 1;
currentTeam = stats[i].teamName;
currentDivision = stats[i].division;
}
}
lineA(out);
}
void printNewMaster(ostream& out, MasterData stats[], int length)
{
for (int i = 0; i < length; i++)
printRecordCSV(out, stats[i]);
}
void printRecordCSV(ostream& out, MasterData d)
{
out << d.playerId << ',';
out << d.firstName << ',';
out << d.lastName << ',';
out << d.division << ',';
out << d.teamName << ',';
out << d.appearances << ',';
out << d.atBats << ',';
out << d.singles << ',';
out << d.doubles << ',';
out << d.triples << ',';
out << d.homeRuns << ',';
out << d.sacFly << ',';
out << d.walks << ',';
out << d.hitByPitch << ',';
out << setprecision(3) << fixed;
out << d.battingAvg << ',';
out << d.OBP << ',';
out << d.sluggingPercent << '\n';
}
void printHeaders(ostream& out)
{
out << setw(11) << "Player ID" << "|";
out << setw(15) << "First Name" << "|";
out << setw(15) << "Last Name" << "|";
out << setw(15) << "Division" << "|";
out << setw(15) << "Team Name" << "|";
out << setw(15) << "Appearances" << "|";
out << setw(10) << "At Bats" << "|";
out << setw(10) << "Singles" << "|";
out << setw(10) << "Doubles" << "|";
out << setw(10) << "Triples" << "|";
out << setw(10) << "Home Runs" << "|";
out << setw(10) << "Sac Flys" << "|";
out << setw(10) << "Walks" << "|";
out << setw(15) << "Hit by Pitch" << "|";
out << setw(15) << "Batting Avg" << "|";
out << setw(15) << "On Base %" << "|";
out << setw(15) << "Slugging %" << "|";
out << "\n";
lineA(out); // line printed for neatness in reports
}
void lineA(ostream& out) //line printed for neatness in reports
{
for (int i = 0; i < 116; i++)
out << "~~~";
out << "\n";
}
void lineB(ostream& out) //line printed for neatness in reports
{
for (int i = 0; i < 116; i++)
out << " ~ ";
out << "\n";
}
//End