Question: C++ Programming You are to develop a program to read Baseball player statistics from an input file. Each player should be stored in a Player

C++ Programming

You are to develop a program to read Baseball player statistics from an input file. Each player should be stored in a Player object. This program builds on to the requirements for Program #2 and #3. Please see the earlier assignments for the definition of a Player Object. This will read in the same type of player data from an input file and write the results to the screen

New Requirements:

You are to implement our collection of baseball players as a binary tree, ordered by the player's name. (Lastname first, then firstname, in the event of people with the same last name). Your Tree class must implement at least the following methods, and any supporting methods you need. Reminder: Because many tree operations are recursive using a node pointer to a root or subroot as input, many operations have a private version that is called with the correct pointer and a public version presented to the user who has no concept of the internal implementation of the tree.

default constructor and destructor

insert - to add a new player to the tree

free - to clean up a tree and free all of the nodes in the tree

count - to return a count of all players in the tree

display - to display the player records, in appropriate order.

updateAvg - to update a particular player's batting average

find - find a player by name

As with the prior programs, you must write a main program to adequately test your methods. Additionally, prompt the user for the name of a player and a new batting average. Find that player in the tree and update his average to the new value. If the player is not found in the tree, indicate that to the user with a message. Prompt the user to perform this operation until the user is ready to quit the program. After the user is finished testing the search and replace for batting averages, print the contents of the tree to the screen in sorted order (ascending) and in reverse order (descending). Please include comments so I can see what is happening.

The input file will have this format: FIRSTNAME LASTNAME POSITION BATTINGAVERAGE. Here is an example:

Chipper Jones 3B 0.303

Rafael Furcal SS 0.281

Hank Aaron RF 0.305

Here is everything from program 3

Player.h

// Class Definition: Player // Version 2 // Added lessThan for ordering // This class defines an object to hold information about // baseball player for use in a player database. //-------------------------------------------------------- #include using namespace std;

class Player { string m_firstName; // player's first name string m_lastName; // player's last name string m_position; // player's primary position double m_battingAverage; // batting average

public: // Default Constructor Player(); // copies data into the object with some simple formatting and // data checking void Initialize(string, string, string, double);

// define methods to read and write simple versions of player data // to/from streams void Read(istream&); void Write(ostream&);

// define get/sets as needed double getBattingAverage(); string getFirstName(); string getLastName(); string getFullName(); string getPosition();

void setFirstName(string); void setLastName(string);

// added for maintaining ordered list by name bool lessThan(const Player &player) const; bool equals(const Player &player) const; };

Player object implementation as a doubly linked list (I need this to be a binary tree now)

OrderedPlayerList.h

#include #include #include "Player.h" using namespace std; //------------------------------------------------------------------------- // Class OrderedPlayerList: Definition, includes member attributes and method (function) // prototypes. PROGRAM 3 MODIFICATION for doubly linked lists // // Implemented as doubly linked list, maintain order ascending by Player's sort operations // // This class depends on (collaborates with) the Player class defined earlier // // Several operations are defined including // default constructor // tests for empty, full // add an item // delete an item // and operations that support traversal of the list // // ADDED locate to perform the new requirement of locating and displaying // the nearest 2 players to one that is not found. // // ADDED a dump operation that will dump the entire List to an output stream // MODIFIED getNext() to return a true / false if succeeded, so we know if we accidentally run off end of a list //------------------------------------------------------------------------

//------------------------------------------------------------------------ // A Linked List depends on the concept of a Node, and Node pointers. // Therefore, the simple Node class will be defined here since it is // very tightly coupled with the List itself. // For now, we will make the Node's internals publicly visible because // the Linked List has to manipulate it. // ---> THERE ARE OTHER WAYS TO ACCOMPLISH TIGHT COUPLING BETWEEN CLASSES //------------------------------------------------------------------------

class Node { public: Player item; // storage space for a Player Node *pNext; // a pointer to the next dynamically allocated Node in the list Node *pPrev; // a pointer to the prior node in the list Node(const Player &player) // used to copy item into newly created nodes for our list { item = player; pNext = NULL; // set link to a valid non-node value pPrev = NULL; } };

class OrderedPlayerList { Node *pFirst; // a pointer that always points to the first item in the list int m_length; // current length of the list (number of items stored) Node *pCurrent; // used for iterations through the list public: // default constructors and destructor OrderedPlayerList(); ~OrderedPlayerList();

// public member functions bool isEmpty(); bool isFull(); bool add(Player player); // add a player to the list bool remove(Player player); // remove a player from the list int getSize(); // returns the count of items stored in the list void resetToStart(); // sets the list iterator to the start of the list void resetToEnd(); // PROG3 MOD: maybe we want to iterate backwards bool getNext(Player &); // gets a copy of the next item from the list when iterating bool getPrev(Player &); // gets prev player when iterating backwards void dump(ostream &); // dumps a list to an output stream, handy for printing everything, or debugging void clear(); // utility to clear out a list and make it ready for new data

// PROG3: NEW FUNCTION bool locate(string, string, ostream &); // use to find and print a player by first and last name or nearest 2 };

Player.cpp

// Class Implementation: Player // Version 2 // Implementation of the methods for a player object // A baseball player has a name, and some simple statistics // Default constructor and initializer functions are provided // as well as simple i/o and gets as needed to supply values // from the object. //------------------------------------------------------------- #include #include #include #include "Player.h" using namespace std;

// Default constructor - set player to predefined values Player::Player() { // use the Initialize method since we have one Initialize("unknown", "unknown", "tbd", 0.0); }

// copies data into the object with some simple formatting and // data checking void Player::Initialize(string first, string last, string pos, double avg) { m_firstName = first; m_lastName = last; m_position = pos; if (avg < 0) avg = -avg; // at least try to correct m_battingAverage = avg; }

// define methods to read and write simple versions of player data // to/from streams

// Read assumes the player's data is in the input stream in the format: // firstname lastname position average with only spaces between the data // no other separator characters are used. This will not work if a player's // name has embedded spaces! void Player::Read(istream &input) { char temp[100]; // using a temporary buffer to read input from stream input >> temp; m_firstName = temp; input >> temp; m_lastName = temp; input >> temp; m_position = temp; input >> m_battingAverage; }

// Write the Player data to an output stream with simple formatting void Player::Write(ostream &out) { out << m_lastName << ", " << m_firstName << ": " << m_position; out << fixed; out << setprecision(3); out << " (" << m_battingAverage << ") "; }

// define get/sets as needed double Player::getBattingAverage() { return m_battingAverage; } string Player::getFirstName() { return m_firstName; } string Player::getLastName() { return m_lastName; } string Player::getFullName() { return m_firstName + " " + m_lastName; } string Player::getPosition() { return m_position; }

void Player::setFirstName(string name) { m_firstName = name; } void Player::setLastName(string name) { m_lastName = name; }

// lessThan function returns true if this Player is less than the one // passed in (comparison done lastname, firstname) // TBD - modify these to handle case-insensitive comparisons! bool Player::lessThan(const Player &player) const { bool less; if (m_lastName.compare(player.m_lastName) < 0) // less than is true less = true; else if (m_lastName.compare(player.m_lastName) == 0 && m_firstName.compare(player.m_firstName) < 0) less = true; else less = false; return less; }

bool Player::equals(const Player &player) const { if (m_lastName.compare(player.m_lastName) == 0 && m_firstName.compare(player.m_firstName) == 0) return true; else return false; }

OrderedPlayerList.cpp

#include "OrderedPlayerList.h" using namespace std; //------------------------------------------------------------------------- // Class OrderedPlayerList: Implementation of function (method) bodies // The OrderedPlayerList is implemented with a linked List and is unbounded. // Interfaces are provided to // add and get layers was well as test the state of the List. // // This modifies the solution for program #2 into program #3 by // adding prev links to each node to use them in a doubly linked list. // //------------------------------------------------------------------------

//------------------------------------------------------------------------ // Default constructor // NewOrderedPlayerList is created with the length set to 0 to reflect that no // items have been entered. //------------------------------------------------------------------------ OrderedPlayerList::OrderedPlayerList() { m_length = 0; pFirst = NULL; // reflect the fact that there are no nodes in this List pCurrent = NULL; } //------------------------------------------------------------------------ // isEmpty: bool // returns true if the List is empty //------------------------------------------------------------------------ bool OrderedPlayerList::isEmpty() { return pFirst == NULL; // use our List pointer now } //------------------------------------------------------------------------ // isFull: bool // returns true if the List is full to capacity //------------------------------------------------------------------------ bool OrderedPlayerList::isFull() { return false; // there is no more restriction on the size of the List! }

//------------------------------------------------------------------------ // add(Player): bool // attempts to add an item to the List. If the List is full return false, // if successful, return true (true represents success) // SORTED VERSION, now we need to find which nodes our new node must go between //------------------------------------------------------------------------ bool OrderedPlayerList::add(Player newPlayer) // add a new item to the List { Node *pNew; // pointer to a new node Node *p, *q; // our pointers that traverse the List looking for a spot to insert pNew = new Node(newPlayer); if (pNew == NULL) // then the allocate did not succeed which would be a critical memory failure! { return false; // did not succeed }

// LOGIC TO STEP THROUGH THE NODES OF A SORTED List TO FIND AN INSERTION----- // SPOT---------------------------------------------------------------------- p = pFirst; q = NULL; // q will be 1 node prior to the one we are looking at while (p != NULL && p->item.lessThan(newPlayer) ) // we are still looking for a spot { q = p; // save the node before the spot p = p->pNext; // move over 1 }

// At this point, q points to the node before and p points to the node that needs to be after // if q is null, this our new first node

if (q == NULL) { pNew->pNext = pFirst; // put our new node in front of pFirst if (pFirst != NULL) { // PROG3 MOD: IF THERE IS ACTUALLY A NODE THERE, make it point back to our new node pFirst->pPrev = pNew; } pFirst = pNew; // then make our new node the new front of the List } else { q->pNext = pNew; // pNew comes after q pNew->pPrev = q; pNew->pNext = p; // and p comes after pNew if (p) p->pPrev = pNew; }

m_length++; // count it return true; // add succeeded }

//------------------------------------------------------------------------ // remove(Player d): bool // locate and remove the given item from the list. If it is in there, // we will have to relink the nodes and free the no longer needed node //------------------------------------------------------------------------- bool OrderedPlayerList::remove(Player player) // remove an item from the List { bool found = false; // return true if successfully removed a node, assume false to begin with

// find a node and remove it

Node *p; // node we are looking at

p = pFirst; // PROG3 MOD: don't need q to follow. If p finds a node we can look back found = false; while (p != NULL && (!p->item.equals(player))) // as long as there is a node and it is not the one we are looking for { p = p->pNext; // move p over to the next node }

if (p != NULL) // need to unlink the node p and free it { if (p->pPrev == NULL) { // if the node in front of p is NULL then we are removing the first node from the List pFirst = p->pNext; delete p; } else { // p is not the first node in thie List, so p->pPrev->pNext = p->pNext; if (p->pNext != NULL) { // PROG3 MOD: ahead to see if there is a node that needs to link back p->pNext->pPrev = p->pPrev; } delete p; } found = true; }

m_length--; return found; } //------------------------------------------------------------------------ // getSize: int // return the internal length of the List, ie number of items stored //------------------------------------------------------------------------ int OrderedPlayerList::getSize() { return m_length; } //------------------------------------------------------------------------ // resetToStart: void // resets the internal iterator counter to the beginning of the List //------------------------------------------------------------------------ void OrderedPlayerList::resetToStart() // sets the List iterator to the start of the List { pCurrent = pFirst; // copy the location of the first node into our iterator } //------------------------------------------------------------------------ // getNext: Player // returns a copy of the next item in the List - as a parameter // NOTE it is up to the user to check to see if there are more items // when iterating! // VERSION 2: MODIFIED to return a success status //------------------------------------------------------------------------ bool OrderedPlayerList::getNext(Player &item) { bool success; if (pCurrent != NULL) { // NEVER TRY TO ACCESS A NULL POINTER'S DATA! item = pCurrent->item; // copy the item stored into parameter, to pass back to caller pCurrent = pCurrent->pNext; // move to next node in the linked List success = true; } else success = false; return success; }

//------------------------------------------------------------------------ // resetToEnd: void // resets the internal iterator counter to the end of the List //------------------------------------------------------------------------ void OrderedPlayerList::resetToEnd() // sets the List iterator to the start of the List { pCurrent = pFirst; // copy the location of the first node into our iterator if (pFirst) { // if the list is not empty move to the end while (pCurrent->pNext != NULL) { pCurrent = pCurrent->pNext; } } } //------------------------------------------------------------------------ // getPrev: Player // returns a copy of the prior item in the List - as a parameter // ADDED with program 3 just because I felt like it //------------------------------------------------------------------------ bool OrderedPlayerList::getPrev(Player &item) { bool success; if (pCurrent != NULL) { // NEVER TRY TO ACCESS A NULL POINTER'S DATA! item = pCurrent->item; // copy the item stored into parameter, to pass back to caller pCurrent = pCurrent->pPrev; // move backward in the doubly linked list success = true; } else success = false; return success; }

//------------------------------------------------------------------------ // clear: void // Clears the MEMORY used up by our List. // IMPORTANT: When working with dynamic memory allocation, it is ESSENTIAL that // the user frees memory nodes when done! // THIS IS A HANDY UTILITY FOR A DESTRUCTOR! //------------------------------------------------------------------------ void OrderedPlayerList::clear() // sets the List iterator to the start of the List { Node *p, *q; p = pFirst; while (p != NULL) { q = p->pNext; // don't lose the link! delete p; // free the node that p points to p = q; // get ready to move over 1 node } pFirst = NULL; pCurrent = NULL; }

//------------------------------------------------------------------------ // locate : PROG3 MOD // add a method to handle the new requirement //------------------------------------------------------------------------ bool OrderedPlayerList::locate(string first, string last, ostream &out) { bool found = false; bool notinlist = false; Player temp; temp.setFirstName(first); // let's use a temporary player object for comparisons temp.setLastName(last);

Node *p, *q; // use p, q to search for the player in this list p = pFirst; // start at beginning of list q = NULL; while (!found && p != NULL && !notinlist) { if (temp.equals(p->item)) found = true; else if (temp.lessThan(p->item)) { // PROG3 MOD: we have gone past the location where our node should be!! notinlist = true; } else { q = p; // need this to know if we've gone off the end of a list p = p->pNext; } } if (found) { // PROG3 MOD p->item.Write(out); } else { // not in the list, but we should have stopped at nearest item or gone off the end of the list! if (p) { // make sure not null, print p and either the one before or after if (p->pPrev) { p->pPrev->item.Write(out); p->item.Write(out); } else { p->item.Write(out); if (p->pNext) p->pNext->item.Write(out); } } else if (q) { // we went off the end of the list, but make sure there is actually at least 1 node there! if (q->pPrev) q->pPrev->item.Write(out); q->item.Write(out); } else { // there appear to be no nodes in this list! out << "There appear to be no Players in your list."; } } return found; }

//------------------------------------------------------------------------ // ~OrderedPlayerList: Destructor // Clears the MEMORY used up by our List. when theOrderedPlayerList is no // longer in use //------------------------------------------------------------------------ OrderedPlayerList::~OrderedPlayerList() { clear(); // use our utility }

main.cpp

// main.cpp - main program file // This program prompts the user for the names of input and output data files. // The input file holds data for the baseball players we are to add to our // list. // // The file is opened and each line is read into a Player object. // The player objects are stored in a Player List implemented as a doubly-linked // list. // // Simple error checking is done to ensure the input file exists before attempting // to read from it. //------------------------------------------------------------------------------------------ #include #include #include "OrderedPlayerList.h" using namespace std;

int main (void) { const int FNLENGTH = 100; // use a reasonable size for filenames char inputFileName[FNLENGTH]; // create buffers to store filenames char outputFileName[FNLENGTH]; ifstream inFile; // create file objects for our 2 files ofstream outFile;

Player currentPlayer; // use to store the next player from the file, or a found player from the list OrderedPlayerList myList; // use to store the player list int i; // loop counter

cout << "Testing a locate in an empty list to make sure it does not crash or error! "; myList.locate("Chipper", "Jones", cout); cout << " ";

// Prompt the user and open the input data file cout << "Please enter the name of your input data file: "; cin >> inputFileName;

inFile.open(inputFileName); if (inFile.fail()) { // file open failed cout << " Error opening input file. Cannot process player data. Exiting Program. " << endl; return 0; // NOTE THIS IS THE ONLY TIME I ALLOW AN EMBEDDED RETURN or BREAK type exit IN A PROGRAM }

// file opened successfully while (!inFile.eof()) { // as long as there are lines of data to be read in // read in a player currentPlayer.Read(inFile); // store in list myList.add(currentPlayer); } inFile.close(); // Now write the player data to the desired output file cout << "Please enter the name of your output data file: "; cin >> outputFileName; outFile.open(outputFileName); // as long as there is space on disk, this won't fail

outFile << "There were " << myList.getSize() << " players in the input data file: " << endl; myList.resetToEnd(); // get the list ready for iteration (BACKWARDS JUST TO CHECK MY LINKS!!! while (myList.getPrev(currentPlayer)) // as long as getPrev returns TRUE for success! { currentPlayer.Write(outFile); // write the most recently retrieved player to the output file outFile << endl; }

outFile.close();

cout << " Your output is stored in the file named " << outputFileName << endl;

cout << " Let's test your find operation a couple of times! " ;

if(myList.locate("Chipper", "Jones", cout)) cout << " --- was found in the list!"; else cout << " --- 2 nearest found the list!"; cout <<" "; // make sure to test where we go off of the end of the list if(myList.locate("Mark", "Jones", cout)) cout << " --- was found in the list!"; else cout << " --- 2 nearest found the list!"; cout << " ";

cout << " End Program 3" << endl;

return 0; }

Thank you for your time, if you need any other info please leave a comment!

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!