Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

This assignment has all of the functionality of previous assignments, but will b

ID: 2246435 • 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:
• The exercises must be added to the list in alphabetical order according to the name of the exercise.
• 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.
Programming Requirements
• 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
from project 4: exerciseData * exercises[arraySize]; we
now have: exerciseData * head;
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 is
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
allocate memory and strcpy() from a temporary string.
• 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 initialized
to nullptr (or NULL).
• When you add new exerciseData structs to the linked list, it is
required that you add them alphabetically sorted according to
the name of the exercise.
• Notice that the delete method returns a bool, similar to
search(). 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 exerciseJournal 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 empty
list.
class exerciseJournal {
exerciseData * head;
int countAndIndex;
char fileName[strSize];
public:
int loadData();
void writeData();
void add();
bool search();
void listAll();
void total();
bool delete();
exerciseJournal();
~exerciseJournal();
};
struct exerciseData {
char * name;
char * date;
char * note;
int time;
int calories;
int maxHeartRate;
exerciseData * next;
};
• The head pointer will point to the first exerciseData struct to be added to the linked list. When you load an
exercise from the file, you will know it is the first struct if
head is equal to nullptr. There are a couple of options to
add new structs to the list. The first method is to set the
head pointer to a new exerciseData struct, and then fill in
the data members. The second way is to set up a new
dynamic exerciseData using a temp pointer, fill in the data
there, and then set head equal to temp. Creating a
temporary pointer will pay dividends for you in the long
run. Look at the code in the textbox to the left to see an
example. This is only an example and you may have added
exercise data in other ways for assignment 4. You may
even want to delegate getting the data to a separate
method, and then have that method return the value of the temporary pointer.
• Adding additional exercises to the linked list is a bit trickier. Your next exercise may have a name that
places it at the beginning of the list, in which case head will point to the new exercise. If the name is
alphabetically at the end, then the new exercise will become the tail of the linked list. Otherwise, it will be
inserted between two other exercises. This is easier to describe with pictures, so
please see left and below. Suppose that the linked list consists of one exercise, called
Elliptical, as pictured to the left.
Elliptical is the last exercise in the list, because the next pointer is set to nullptr (or
NULL). This is signified with a slashing line in the next pointer field. Now let’s add Basketball.
Notice that Basketball comes before Elliptical alphabetically, so Basketball
becomes the head of the linked list. The head pointer is moved from
Elliptical to Basketball, and the next pointer for Basketball is made to point
at Elliptical. Elliptical-next is already set to nullptr, and the list is updated.
Now let’s add Cardio to the list.
Cardio comes after Basketball alphabetically, but before Elliptical.
So, the next pointer for Basketball is made to point at Cardio,
Cardio-next pointer is set to point at Elliptical, and the list is
updated.
The last possibility is to add an exercise to the end of the list. Strength comes after Elliptical alphabetically,
so it will be added to the end of the list. The next pointer for Elliptical will be set to point to Strength, the
next pointer for Strength will be set to nullptr, and the
list is updated.
Deleting an exercise struct is the opposite of adding one,
but is a little easier, because we already have the data,
and don’t need to allocate any memory. Suppose we
wanted to delete Strength. Then Elliptical-next pointer would be set to nullptr, and we could delete
Strength. Suppose we wanted to remove Basketball from the list. Since Basketball is the head, we need the
head pointer to point at Cardio:
exerciseData * temp; temp = head; head = head->next; delete temp; To delete
Cardio, we would set a temporary pointer to it, have Basketball-next point to Elliptical, and then delete
Cardio by deleting the temporary pointer. Suppose that we have searched for and found Cardio, so prev
points to Basketball and cur points to Cardio:
exerciseData *prev, *cur;
prev->next = cur->next; // Basketball now points to Elliptical.
delete cur;
void exerciseJournal::add() {
char input[STR_SIZE];
exerciseData * temp = new exerciseData;
cout << "What is the exercise name? ";
cin.getline(input, STR_SIZE);
temp->name = new char[strlen(input) + 1];
strcpy(temp->name, input);
// Add other data items here.
temp->next = nullptr;
if (head == nullptr)
head = temp;
// else code will go here, for adding
// other exerciseData structs.
return;
}

These are my code

exerciseHeader.hpp

#ifndef EXERCISE_HPP

#define EXERCISE_HPP

#include <iostream>

using namespace std;

const int strSIZE = 256;

const int Array = 128;

struct exerciseData {

char name[strSIZE];

char date[strSIZE];

char note[strSIZE];

int time;

int calories;

int maxHeartRate;

};

class exerciseJournal {

exerciseData practice[Array];

int countAndIndex;

char fileName[strSIZE];

public:

int loadData();

void writeData();

void add();

int search();

void listAll();

};

int loadData(exerciseData exerciseList[]);

int _search(exerciseData exerciseList[], int _count);

void _list(exerciseData exerciseList[], int _count);

#endif

main.cpp

#include "exerciseHeader.hpp"

#include "implementation.cpp"

using namespace std;

int main()

{

int time;

int calories;

int h_rates;

int o;

int countAndIndex;

char name[strSIZE];

int date[strSIZE];

char note[strSIZE];

exerciseJournal exerJournal;

cout << "Welcome to the SAMM exercise tracking program.";

int a = exerJournal.loadData();

cout << "Successfully loaded " << a << " activities ";

while (o != 'q')

{

cout << "What would you like to do: (l)ist all, (s)earch by name, (a)dd an exercise, or (q)uit? ";

cin.getline(0,1);

switch (o)

{

case 'l':

{

_list(exerciseList, a);

break;

}

case 's':

{

int u;

u = _search(exerciseList, a);

cout << " " << u << "activities found. ";

break;

}

case 'a':

{

cout << "Thank you for using the exercise tracking program.";

return 0;

}

implementation.cpp

#include "exerciseHeader.hpp"

#include <iostream>

#include <fstream>

#include <cstring>

int exerciseJournal::loadData()// pass the array of structs, return total exercises read.

{

//file stream and other varibles

//using char array instead of string

char file[256];

char ch;

exerciseData temp;

int i = 0;

cout << "Enter file to load ";

cin.getline(file, 256);

ifstream fin(file); //reading line by line

while (!fin.eof())

{

fin.getline(temp.name,strSIZE, ',');

fin.getline(temp.date,strSIZE, ',');

fin.getline(temp.note,strSIZE, ',');

fin >> temp.time;

fin.get(ch);

fin >> temp.calories;

fin.get(ch);

fin >> temp.maxHeartRate;

fin.get(ch);

i++;

}

return i - 1;

int _search(exerciseData exerciseList[], int _count);// pass the array and the number of items in the array.

char act[strSIZE];

cout << "What activity would you like to search for? ";

cin.getline(act, strSIZE);

for (int i = 0; i < countAndIndex; i++)

{

if (strcmp(practice[i].name, act) == 0)

{

countAndIndex;

//if (countAndIndex == 1)

{

cout << "Here are the activities matching " << act << endl;

cout << "Date Time Calories MaxHeartRate Note ";

}

cout << exerciseList[i].date << " " << exerciseList[i].time << " " << exerciseList[i].calories << " " << exerciseList[i].h_rates << " " << exerciseList[i].note << endl;

}

}

return 0;

}

void _list(exerciseData exerciseList[], int _count)// Print all data in the list.

{

int countAndIndex;

cout << "The exercises are as follows " << endl;

cout << "Name Date Time Calories MaxHeartRate Note ";

for (int i = 0; i < countAndIndex; i++)

{

cout << exerciseJournal[i].name << " " << exerciseList[i].date << " " << exerciseList[i].time << " " << exerciseList[i].calories << " " << exerciseList[i].h_rates << " " << exerciseList[i].note << endl;

}

}

void exerciseJournal::add()

{

char y[256], b[256], c[256];

int d, e, f;

char p;

cout << "What exercise activity did you do? ";

cin >> y;

cout << "What was the date (mm/dd/yy): ";

cin >> b;

cout << "How many minutes? ";

cin >> d;

cout << "How many calories did you burn? ";

cin >> e;

cout << "What was you max heart rate? ";

cin >> f;

cout << "Do you have any notes to add? ";

cin.getline(c, 50);

cout << "OK, " << y << " on " << b << ". Time: " << d << ", Calories: " << e << ", Max heartrate: " << f << ": Note: " << c << " Record the activity time and calories (y/n)? ";

cin >> p;

if (p == 'y')

{

strcpy(exerciseList[a].name, y);

strcpy(exerciseList[a].date, b);

strcpy(exerciseList[a].note, c);

exerciseList[a].time = d;

exerciseList[a].calories = e;

exerciseList[a].h_rate = f;

cout << "Your activity info has been recorded.";

countAndIndex;

}

else

{

cout << "Enter again";

goto there;

}

}

exercise text

Elliptical,06/10/17,great workout,40,400,135
Treadmill,06/12/17,doggin it,20,150,120
Stationary Bike,06/15/17,felt good,30,200,130
Elliptical,06/20/17,great-worked out with Mike,45,350,140

Explanation / Answer

Debugging is the process of finding compile time and run time errors in the code. Compile time errors occur due to misuse of C language constructs. Most of the compile time errors can be overcome with careful attention to language syntax and use. Finding syntax errors is the first step in a debugging process. A typical C project that contains main.c, lib.h and lib.c can be compiled at once with % gcc –ansi –Wall –pedantic lib.c main.c –o exec It is also good to compile all source code files separately, so programmer can deal with errors more locally. For example, the main.c and lib.c in the above example can be compiled separately with –c flag. % gcc –c –ansi –Wall –pedantic main.c % gcc –c –ansi –Wall –pedantic lib.c In this case, no executable is created and two files named main.o and lib.o will be created if source code is successfully compiled. Later on, one can create the executable by % gcc lib.o main.o –o exec Often dealing with syntax errors is the easiest part of debugging. Once you remove common errors like, missing semicolons, variable type mismatches, incorrect passing of Copyright @ 2009 Ananda Gunawardena arguments, undefined or out of scope variables etc we can begin to execute the code. Run time errors are the hardest to deal with. Run time errors can cause program to crash, or give you the incorrect output. First step in dealing with run time errors is to remove reasons for program to crash. Some of the most common errors of program crash are, dereferencing memory that has not been allocated, freeing memory that was already freed once, opening a file that does not exists, reading incorrect or non-existent data or processing command line arguments that have not been provided. Although debugging a program is an art, it is important to develop a systematic process to debug. Often the best way to deal with errors is to not to introduce them in the first place. Developing individual functions and testing them to make sure they perform as expected is quite important. For each function, you provide the input and test for the expected output. You also need to deal with edge cases as they are most often the cause of the problem. Also it is important to test the input files to make sure that they are valid. One cannot assume that all input files are valid. For example, an input file may have a null line at the end of the file causing the program to behave in an unexpected manner. In the next section we will discuss some of the most common type of syntax and run time errors. Most Common Type of Errors There are no hard and fast rules about debugging code. But some errors occur more frequently than the others. We will start with a list of syntax errors that occur more frequently. Here is some of the most common type of errors. • Missing/misplaced semicolons The most common type of error in the early stages of development. Each statement in a program must be separated by a semi colon. But avoid putting a semicolon at the end of a loop declaration. This error can be corrected easily as compiler will provide enough clues as to the line where semi colons are missing or misplaced