Problem Statement You are to develop a program to read Baseball player statistic
ID: 3812084 • Letter: P
Question
Problem Statement
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 adds on to the requirements for Program #2. Please see that assignment. This will read in the same type of player data from an input file and write the results to an output file.
New Requirements
You are to re-implement the PlayerList data structure/data type that stores players using a doubly linked-list. Store the players in the list in alphabetical order (By lastname, use firstname to further distinguish in the event there is more than 1 player with the same last name). You must implement the same operations on this new version of PlayerList that were required for assignment #2. In addition, you will need to add at least two new operations to support the following requirement:
We are going to use our player list as a sort of directory, or white pages of sorts. Prompt the user to look up a player by first and last name. If the player is found in the list, print out only that player's record. If the player is not found, you should print the two nearest players (the 1stone before and the1stone after) to the desired player. Note -in order for this to work, your operations are going to have to have some concept of where the search stops in the list (in the middle, at the end, etc). You can implement the printer operation as a method on the list so it has this information at its disposal.
Some Examples-Suppose I have the following players in my list
Hank Aaron
Andrew Jones
Chipper Jones
John Smith
Josh Thomas
If I search for Hank Aaron, only Hank Aaron should be displayed as found in the list.
If I search for Mark Jones, then Chipper Jones and John Smith should be displayed as two nearest to thedesired information(before and after).
If I search for Jack Williams, then John Smith and Josh Thomas should be displayed.
Prompt the user to perform lookups until the user is ready to quit the program (i.e. use a while loop of some sort).
Here is what I have so far.
main.cpp fille
#include <iostream>
#include <fstream>
#include "PlayerList.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
PlayerList myList; // use to store the player list
int i; // loop counter
// 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.resetToStart(); // get the list ready for iteration
while (myList.getNext(currentPlayer)) // as long as getNext 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.find("Chipper", "Jones", currentPlayer)) {
cout << "I found this player: ";
currentPlayer.Write(cout);
cout << endl;
}
else
cout << "I could not find the requested player ";
if (myList.find("Mark", "Jones", currentPlayer)) {
cout << "I found this player: ";
currentPlayer.Write(cout);
cout << endl;
}
else
cout << "I could not find the requested player ";
cout << " End Program 2" << endl;
return 0;
}
Player.h file
#include <iostream>
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.cpp file
#include <iostream>
#include <string>
#include <iomanip>
#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;
}
PlayerList.h file
#include <iostream>
#include <fstream>
#include "Player.h"
using namespace std;
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 previous 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
}
};
class PlayerList {
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
PlayerList();
~PlayerList();
// 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
bool getNext(Player &); // gets a copy of the next item from the list when iterating
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
bool find(string, string, Player &); // use to find a player by first and last name
};
PlayerList.cpp file
#include "PlayerList.h"
using namespace std;
//------------------------------------------------------------------------
// Default constructor
// NewOrderedPlayerList is created with the length set to 0 to reflect that no
// items have been entered.
//------------------------------------------------------------------------
PlayerList::PlayerList() {
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 PlayerList::isEmpty() {
return pFirst == NULL; // use our List pointer now
}
//------------------------------------------------------------------------
// isFull: bool
// returns true if the List is full to capacity
//------------------------------------------------------------------------
bool PlayerList::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 PlayerList::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
pFirst = pNew; // and make our new node the new front of the List
}
else {
q->pNext = pNew; // pNew comes after q
pNew->pNext = p; // and p comes after 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 PlayerList::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
Node *q; // previous node right before p to enable us to unlink a node
p = pFirst;
q = NULL;
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
{
q = p; // save where we are now
p = p->pNext; // move p over to the next node
}
if (p != NULL) // need to unlink the node p and free it
{
if (q == 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
q->pNext = p->pNext; // reroute prior node link to the one after p
delete p;
}
found = true;
}
m_length--;
return found;
}
//------------------------------------------------------------------------
// getSize: int
// return the internal length of the List, ie number of items stored
//------------------------------------------------------------------------
int PlayerList::getSize()
{
return m_length;
}
//------------------------------------------------------------------------
// resetToStart: void
// resets the internal iterator counter to the beginning of the List
//------------------------------------------------------------------------
void PlayerList::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 PlayerList::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;
}
//------------------------------------------------------------------------
// 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 PlayerList::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;
}
//------------------------------------------------------------------------
// find(string, string, Player): returns boolean
// Given a first name and last name, this operation will provide a copy
// of the player that matches. It will return a true/false status to indicate
// success
//------------------------------------------------------------------------
bool PlayerList::find(string first, string last, Player &foundPlayer) {
bool found = false;
Player temp;
temp.setFirstName(first); // let's use a temporary player object for comparisons
temp.setLastName(last);
Node *p; // use p to search for the player in this list
p = pFirst; // start at beginning of list
while (!found && p != NULL) {
if (temp.equals(p->item))
found = true;
else
p = p->pNext;
}
if (found) {
foundPlayer = p->item; // make a copy to pass out as parameter
}
return found;
}
//------------------------------------------------------------------------
// ~PlayerList: Destructor
// Clears the MEMORY used up by our List. when theOrderedPlayerList is no
// longer in use
//------------------------------------------------------------------------
PlayerList::~PlayerList() {
clear(); // use our utility
}
//------------------------------------------------------------------------
// dump: void
// Write a loop to step through the nodes in the List and print their
// items to the output stream
//------------------------------------------------------------------------
void PlayerList::dump(ostream &o)
{
// TODO: Exercise left for the student
}
Explanation / Answer
void PlayerList::dump(ostream &o) //To print the items in the list
{
Node *p, *q;
p = pFirst;// getting the first pointer in the list
int i=0;
while (p != NULL) {
q = p->pNext; //storing the next pointer
o<<"item no %d"<<i;
o<<p->item.m_firstName;
o<<p->item.m_lastName;
o<<p->item.m_position;
o<<p->m_battingAverage;
o<<" "
i=i+1;
p = q;
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.