This assignment has all of the functionality of previous assignments, but will b
ID: 2246405 • Letter: T
Question
This assignment has all of the functionality of previous
assignments, but will be rewritten to use a dynamically allocated
linked list. Use Valgrind to check your code for leaks. Here are the two new requirements for this project:
1. The exercises must be added to the list in alphabetical order according to the name of the exercise.
2. In addition to the methods listed in project 3 and 4, you will create one more method and menu option to delete an exercise from the list.
So, this assignment will have the same user-controlled loop as assignment 4 plus the delete option. The add() and the loadData() methods will need to be rewritten to insert new exercises in alphabetical order. Just like assignment 4, your program will write the data back to the same file as the input file at program termination, using the writeData() method. Don’t forget to make a backup copy of assignment 4 before modifying the source code for assignment 5.
-------------------------------------------------------
The files from Project 4 are below.
-------------------------------------------------------
// common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#include <cstring>
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
const int strSize = 128;
const int arraySize = 100;
bool any(const char cs[], int (*condition)(int));
void qCString(const char question[], char answer[], const int ss =
strSize);
void qGCString(const char question[], char answer[], const int ss =
strSize);
int qInt(const char question[]);
int qPInt(const char question[]);
char qChar(const char question[]);
bool contains(const char cs[], const char c);
char qSel(const char question[], const char allowed[]);
bool qYN(const char question[]);
void qFH(const char question[], ifstream& fh);
void qFN(const char question[], char fn[], const int ss = strSize);
#endif
—————————————————————————————————————————————————
// exercise.txt
Elliptical,07/05/17,45,450,130,great workout
Treadmill,07/06/17,30,220,120,great workout
Stationary Bike,07/07/17,30,280,130,great workout
Elliptical, 07/08/17,30,300,120,great workout
————————————————————————————————————————
// exerciseJournal.cpp
#include "exerciseJournal.h"
void allocateAndCopy(char* &dest, const char* src){
dest = new char[strlen(src) + 1] ;
strcpy(dest, src);
}
exerciseData* parseActivity(ifstream &fh) {
char temp[strSize];
exerciseData *edata = new exerciseData;
fh.getline(temp, strSize, ',');
allocateAndCopy(edata->name, temp);
fh.getline(temp, strSize, ',');
allocateAndCopy(edata->date, temp);
fh >> edata->time;
fh.ignore();
fh >> edata->calories;
fh.ignore();
fh >> edata->maxHeartRate;
fh.ignore();
fh.getline(temp, strSize);
allocateAndCopy(edata->note, temp);
return edata;
}
template <class A, class B, class C, class D, class E, class F>
void showRow(A name, B date, C time, D calories, E maxHeartRate, F note)
{
cout << left
<< setw(20) << name
<< setw(10) << date
<< setw(10) << time
<< setw(10) << calories
<< setw(15) << maxHeartRate
<< setw(12) << note
<< ' ';
}
exerciseData* queryActivty() {
exerciseData* edata = new exerciseData;
char temp[strSize];
qGCString("What workout did you do?", temp);
allocateAndCopy(edata->name, temp);
qGCString("What was the date (mm/dd/yy):", temp);
allocateAndCopy(edata->date, temp);
edata->time = qPInt("How much time?");
edata->calories = qPInt("How many calories?");
edata->maxHeartRate = qPInt("What was your max heart rate?");
qGCString("Do you have anything to add?", temp);
allocateAndCopy(edata->note, temp);
return edata;
}
void exerciseJournal::queryFilename() {
qFN("What is the name of the file to load?",
fileName);
}
int exerciseJournal::loadData() {
countAndIndex = 0;
ifstream fh(fileName);
if(!fh.is_open())
{
cout << "Could not open input file " << fileName << endl;
return 0;
}
while (true) {
eds[countAndIndex] = parseActivity(fh);
if (fh.eof())
break;
countAndIndex++;
if (countAndIndex >= arraySize)
break;
}
return countAndIndex;
}
void exerciseJournal::writeData() {
ofstream of(fileName);
if (of.is_open())
for (int i = 0; i < countAndIndex; i++)
of << eds[i]->name << ','
<< eds[i]->date << ','
<< eds[i]->time << ','
<< eds[i]->calories << ','
<< eds[i]->maxHeartRate << ','
<< eds[i]->note << ' ';
else
cerr << "Could not open " << fileName << " for writing. ";
of.close();
}
void exerciseJournal::add() {
if (countAndIndex >= arraySize) {
cout << "You need to stop workingout. ";
} else {
eds[countAndIndex] = queryActivty();
if (qYN("Record the data (y/n)?")) {
countAndIndex++;
cout << "Activity info saved. ";
}
else
delete eds[countAndIndex];
}
}
bool exerciseJournal::search(){
char name[strSize];
bool found = false;
qGCString("What exercise activity would you like to look up?", name);
cout << "Here are the activities matching" << name << ": ";
showRow("Name","Date","Time","Calories","Max Heartrate","Note");
for(int i = 0; i < countAndIndex; i++)
if(strcmp(name, eds[i]->name)==0)
{
found = true;
showRow(eds[i]->name,eds[i]->date,eds[i]->time,
eds[i]->calories,eds[i]->maxHeartRate, eds[i]->note);
}
return found;
}
void exerciseJournal::listAll(){
showRow("Name","Date","Time","Calories","Max Heartrate","Note");
for (int i = 0; i < countAndIndex; i++)
showRow(eds[i]->name,eds[i]->date,eds[i]->time,eds[i]->calories,eds[i]->maxHeartRate, eds[i]->note);
}
exerciseJournal::~exerciseJournal(){
for(int i = 0; i < countAndIndex; i++)
delete eds[i];
}
——————————————————————————————————————————————
// exerciseJournal.h
#ifndef _EXERCISE_JOURNAL_H_
#define _EXERCISE_JOURNAL_H_
#include "common.h"
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
struct exerciseData{
char *name;
char *date;
char *note;
int time;
int calories;
int maxHeartRate;
~exerciseData(){
delete []name;
delete []date;
delete []note;
}
};
class exerciseJournal{
exerciseData* eds[arraySize];
int countAndIndex;
char fileName[strSize];
public:
void queryFilename();
int loadData();
void writeData();
void add();
bool search();
void listAll();
~exerciseJournal();
};
#endif
For assignment 4, we used an array of struct pointers, but for this version, we won't be declaring an array at all. We will be replacing the array with a pointer to the exerciseData struct called the head pointer. Look at the class exercisejournal. Notice that instead of the array eat-at from project 4: exerciseDataexercises [arraySize] we now have: exerciseDatahead; Now look at the exerciseData struct to the right. At the bottom of the struct declaration, there is a new member called next. The next pointer iseartate the link to the next struct in the list. Everything else with the struct will be the same as it was for assignment 4, namely, dynamically allocated c-strings. Use the same method to I have also added a constructor prototype to the exerciseJournal class. The constructor has become necessary for this assignment, so that the head pointer can be initializedbls char filetsmelstrsizel: When you add new exerciseData structs to the linked list, it is required that you add them alphahetically sorted according to the name of the exercise. Notice that the delete method returns a bool, similar to search0. If the user wishes to delete an exercise that doesn't exist in the list, return false, so that the calling function can report an error. Otherwise return true, so that the calling function can report successful deletion. Strategies for using a linear linked list . When you instantiate your exerciselournal object, it is important to set the head pointer to nullptr (or NULL if your compiler doesn't support nullptr). Using nullptr is important because if a pointer is set to this value, it means that it doesn't point to anything, and is therefore the end of the list. Use your constructor for exerciseJournal to set head to nullptr. By setting head nullptr; you will be starting off with an emptyExplanation / Answer
Given below are the modified files. You have not given the common.cpp and main.cpp files. Since I had answered your previous question, I had those files with me. Please take the modified files from below. Request you to rate the answer if it helped. Thank you.
exerciseJournal.h
// exerciseJournal.h
#ifndef _EXERCISE_JOURNAL_H_
#define _EXERCISE_JOURNAL_H_
#include "common.h"
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
struct exerciseData{
char *name;
char *date;
char *note;
int time;
int calories;
int maxHeartRate;
exerciseData *next;
~exerciseData(){
delete []name;
delete []date;
delete []note;
}
};
class exerciseJournal{
exerciseData *head;
int countAndIndex;
char fileName[strSize];
public:
exerciseJournal();
void queryFilename();
int loadData();
void writeData();
void add();
void addData(exerciseData *ed); //to add in sorted order
bool deleteData(); //deletes the first occurence of an exercise with specified name
bool search();
void listAll();
~exerciseJournal();
};
#endif// exerciseJournal.h
#ifndef _EXERCISE_JOURNAL_H_
#define _EXERCISE_JOURNAL_H_
#include "common.h"
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
struct exerciseData{
char *name;
char *date;
char *note;
int time;
int calories;
int maxHeartRate;
exerciseData *next;
~exerciseData(){
delete []name;
delete []date;
delete []note;
}
};
class exerciseJournal{
exerciseData *head;
int countAndIndex;
char fileName[strSize];
public:
exerciseJournal();
void queryFilename();
int loadData();
void writeData();
void add();
void addData(exerciseData *ed); //to add in sorted order
bool deleteData(); //deletes the first occurence of an exercise with specified name
bool search();
void listAll();
~exerciseJournal();
};
#endif
exerciseJournal.cpp
// exerciseJournal.cpp
#include "exerciseJournal.h"
void allocateAndCopy(char* &dest, const char* src){
dest = new char[strlen(src) + 1] ;
strcpy(dest, src);
}
exerciseData* parseActivity(ifstream &fh) {
char temp[strSize];
fh.getline(temp, strSize, ',');
if(fh.eof())
return NULL;
exerciseData *edata = new exerciseData;
allocateAndCopy(edata->name, temp);
fh.getline(temp, strSize, ',');
allocateAndCopy(edata->date, temp);
fh >> edata->time;
fh.ignore();
fh >> edata->calories;
fh.ignore();
fh >> edata->maxHeartRate;
fh.ignore();
fh.getline(temp, strSize);
allocateAndCopy(edata->note, temp);
edata->next = NULL;
return edata;
}
template <class A, class B, class C, class D, class E, class F>
void showRow(A name, B date, C time, D calories, E maxHeartRate, F note)
{
cout << left
<< setw(20) << name
<< setw(10) << date
<< setw(10) << time
<< setw(10) << calories
<< setw(15) << maxHeartRate
<< setw(12) << note
<< ' ';
}
exerciseData* queryActivty() {
exerciseData* edata = new exerciseData;
char temp[strSize];
qGCString("What workout did you do?", temp);
allocateAndCopy(edata->name, temp);
qGCString("What was the date (mm/dd/yy):", temp);
allocateAndCopy(edata->date, temp);
edata->time = qPInt("How much time?");
edata->calories = qPInt("How many calories?");
edata->maxHeartRate = qPInt("What was your max heart rate?");
qGCString("Do you have anything to add?", temp);
allocateAndCopy(edata->note, temp);
edata->next = NULL;
return edata;
}
exerciseJournal::exerciseJournal()
{
head = NULL;
}
void exerciseJournal::queryFilename() {
qFN("What is the name of the file to load?",
fileName);
}
int exerciseJournal::loadData() {
countAndIndex = 0;
ifstream fh(fileName);
if(!fh.is_open())
{
cout << "Could not open input file " << fileName << endl;
return 0;
}
while (true) {
exerciseData *ed = parseActivity(fh);
if(ed != NULL)
addData(ed);
else
break;
countAndIndex++;
}
return countAndIndex;
}
void exerciseJournal::writeData() {
ofstream of(fileName);
if (of.is_open())
{
exerciseData *curr = head;
while(curr != NULL)
{
of << curr->name << ','
<< curr->date << ','
<< curr->time << ','
<< curr->calories << ','
<< curr->maxHeartRate << ','
<< curr->note << ' ';
curr = curr->next;
}
}
else
cerr << "Could not open " << fileName << " for writing. ";
of.close();
}
//add exercise data in a sorted order
void exerciseJournal::addData(exerciseData *ed)
{
if(ed == NULL)
return;
if(head == NULL)
head = ed;
else
{
exerciseData *curr = head, *prev = NULL;
//find the correct place to add
while(curr != NULL)
{
if(strcmp(ed->name, curr->name) < 0) //found the corrrect place to add
break;
prev = curr;
curr = curr->next;
}
//now add the node in the place we reached
ed->next = curr;
if(prev == NULL) //there is no previous node, i.e we are adding before head
head = ed;
else
prev->next = ed;
}
}
void exerciseJournal::add() {
if (countAndIndex >= arraySize) {
cout << "You need to stop workingout. ";
} else {
exerciseData *ed = queryActivty();
if (qYN("Record the data (y/n)?")) {
addData(ed);
cout << "Activity info saved. ";
}
else
delete ed;
}
}
bool exerciseJournal::deleteData()
{
char name[strSize];
qGCString("What exercise activity would you like to delete?", name);
exerciseData *curr = head, *prev = NULL;
while(curr != NULL)
{
if(strcmp(name, curr->name)==0)
{
break;
}
prev = curr;
curr = curr->next;
}
if(curr == NULL)
return false;
else
{
if(prev == NULL) //deleting head node?
head = curr->next;
else
prev->next = curr->next;
delete curr;
return true;
}
}
bool exerciseJournal::search(){
char name[strSize];
bool found = false;
qGCString("What exercise activity would you like to look up?", name);
cout << "Here are the activities matching" << name << ": ";
showRow("Name","Date","Time","Calories","Max Heartrate","Note");
exerciseData *curr = head;
while(curr != NULL)
{
if(strcmp(name, curr->name)==0)
{
found = true;
showRow(curr->name,curr->date,curr->time,
curr->calories,curr->maxHeartRate, curr->note);
}
curr = curr->next;
}
return found;
}
void exerciseJournal::listAll(){
showRow("Name","Date","Time","Calories","Max Heartrate","Note");
for (exerciseData *curr = head; curr != NULL; curr = curr->next)
showRow(curr->name,curr->date,curr->time,curr->calories,curr->maxHeartRate, curr->note);
}
exerciseJournal::~exerciseJournal(){
exerciseData *curr = head, *temp;
while(curr != NULL)
{
temp = curr->next;
delete curr;
curr = temp;
}
}
main.cpp
// main.cpp
#include "common.h"
#include "exerciseJournal.h"
#include <iostream>
using namespace std;
int main() {
exerciseJournal journal;
cout << "Welcome to the exercise tracking program. ";
journal.queryFilename();
journal.loadData();
while (true) {
const char s = qSel("What would you like to do: (l)ist all, (s)earch by"
" name, (a)dd an exercise, (d)elete an exercise or (q)uit? :", "lsadq");
if (s == 'l') {
journal.listAll();
} else if (s == 's') {
journal.search();
} else if (s == 'a') {
journal.add();
}else if (s == 'd'){
if(!journal.deleteData())
cout << "Exercise not found." << endl;
}else if (s == 'q') {
break;
}
}
journal.writeData();
cout << "Thank you for using the exercise tracking program. ";
return 0;
}
output
Welcome to the exercise tracking program.
What is the name of the file to load? exercise.txt
What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, (d)elete an exercise or (q)uit? : l
Name Date Time Calories Max Heartrate Note
Elliptical 07/05/17 45 450 130 great workout
Elliptical 07/08/17 30 300 120 great workout
Stationary Bike 07/07/17 30 280 130 great workout
Treadmill 07/06/17 30 220 120 great workout
What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, (d)elete an exercise or (q)uit? : a
What workout did you do? Cycle
What was the date (mm/dd/yy): 07/10/17
How much time? 20
How many calories? 150
What was your max heart rate? 120
Do you have anything to add? good
Record the data (y/n)? y
Activity info saved.
What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, (d)elete an exercise or (q)uit? : l
Name Date Time Calories Max Heartrate Note
Cycle 07/10/17 20 150 120 good
Elliptical 07/05/17 45 450 130 great workout
Elliptical 07/08/17 30 300 120 great workout
Stationary Bike 07/07/17 30 280 130 great workout
Treadmill 07/06/17 30 220 120 great workout
What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, (d)elete an exercise or (q)uit? : d
What exercise activity would you like to delete? Elliptical
What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, (d)elete an exercise or (q)uit? : l
Name Date Time Calories Max Heartrate Note
Cycle 07/10/17 20 150 120 good
Elliptical 07/08/17 30 300 120 great workout
Stationary Bike 07/07/17 30 280 130 great workout
Treadmill 07/06/17 30 220 120 great workout
What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, (d)elete an exercise or (q)uit? : d
What exercise activity would you like to delete? Treadmill
What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, (d)elete an exercise or (q)uit? : l
Name Date Time Calories Max Heartrate Note
Cycle 07/10/17 20 150 120 good
Elliptical 07/08/17 30 300 120 great workout
Stationary Bike 07/07/17 30 280 130 great workout
What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, (d)elete an exercise or (q)uit? : q
Thank you for using the exercise tracking program.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.