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

You will load previous exercise sessions from a text file when the program start

ID: 3856502 • Letter: Y

Question

You will load previous exercise sessions from a text file when the program starts, and store the information in an array of structs. Use a function for this (see below for function prototype suggestions). Take a look at the struct in the textbox below to get an idea of the information that needs to be read from the file and stored for each exercise session. The items are: name, date, note, time, calories, and maximum heartrate. When the user adds new activities, add them to the array of structs also. There is no need to write the data back to a text file with this project. In other words, you only need to read data from a file, not write data to a file. Also add the ability to list all exercises in memory and to search for a specific exercise. Create separate functions for this functionality also. Notice in the example output below that there might be more than match, so make sure to output all of the entries that match the given name.

Example File

There will be an example text file in the assignment area along with this assignment, but you may create your own. If you create your own file, do not add headers or other file details, and do not use a different format. Do not assume that you know how many items are in the text file. This example has 4, but you must be able to handle a file with any number of items (within reason; the size of your array will be the limit, see below). The example file uses one line per workout, and it uses commas to separate the values:

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

Textbox:

struct exerciseData {

char name[strSize];

char date[strSize];

char note[strSize];

int time;

int calories;

int maxHeartRate;

};

Example Program Output

Welcome to the exercise tracking program.

What is the name of the exercise data text file to load? exercise.txt

Successfully loaded 4 activities.

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

The exercises are as follows:

Name             Date      Time Calories   Max Heartrate Note

Elliptical       06/10/17 40    400        135            great workout

Treadmill        06/12/17 20    150        120            doggin it

Stationary Bike 06/15/17 30    200        130            felt good

Elliptical       06/20/17 45    350        140            great-worked out with Mike

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

What exercise activity did you do? Free Weights

What was the date (mm/dd/yy): 06/21/17

How many minutes? 60

How many calories did you burn? 160

What was you max heart rate? 110

Do you have any notes to add? Felt the burn

OK, Free Weights on 06/21/17. Time: 60, Calories: 160, Max heartrate: 110: Note: felt the burn.

Record the activity time and calories (y/n)? y

Your activity info has been recorded.

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

The exercises are as follows:

Name             Date      Time Calories   Max Heartrate Note

Elliptical       06/10/17 40    400        135            great workout

Treadmill        06/12/17 20    150        120            doggin it

Stationary Bike 06/15/17 30    200        130            felt good

Elliptical       06/20/17 45    350        140            great-worked out with Mike

Free Weights     06/21/17 60    160        110            felt the burn

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

What activity would you like to search for? Elliptical

Here are the activities matching Elliptical:

Date      Time Calories   Max Heartrate Note

06/10/17 40    400        135            great workout

06/20/17 45    350        140            great-worked out with Mike

Found a total of 2 entries.

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

Thank you for using the exercise tracking program.

Program Functions

You must write at least 3 functions to implement this project, in addition to main(). The 3 functions are:

int loadData(exerciseData exerciseList[]); // pass the array of structs, return total exercises read.

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

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

Program Requirements

In addition to the requirements listed below, follow all of the requirements for project 1: No literals, no globals, must compile with g++, no string objects or stl containers, no c-style input or output, guard against bad data (for cin only; no need to guard against bad data from the file).

You must use the <iomanip> library and setw() to output the data in column-formatted output.

Guard against index out of bounds / buffer overflow. See below in strategies.

Do not use cin extraction (>>) to read data into c-strings, because this is a security issue. Use cin.getline() instead.

The array of exerciseData structs must be declared in main, and the struct must be defined globally. This means that you must pass the array of structs to your functions as an argument.

Only use c-strings, not strings

Explanation / Answer

main.cpp
---------------------------------------------------
/ qFH("What is the name of the exercise data text file to load?", fh);

#include <cstring>
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

// Reusable stuff -------------------------------

const int STRING_SIZE = 64;
const int LIST_SIZE = 4096;

// Return true if any char in cs satisfies condition.
// condition has type 'int (*condition)(int)' to match <cstring> convention.
bool any(const char cs[], int (*condition)(int)) {
for (int i = 0; cs[i]; i++)
    if (condition(cs[i]))
      return true;
return false;
}

// The q prefix indicates a function that queries the user.

// Ask the user a question. Dump the response into answer.
void qCString(const char question[], char answer[],
              const int ss = STRING_SIZE) {
cout << question << ' ';
cin.getline(answer, ss);
}

// Bother the user until they enter a string containing graphical characters.
void qGCString(const char question[], char answer[],
               const int ss = STRING_SIZE) {
qCString(question, answer, ss);
while (!any(answer, isgraph))
    qCString("Try again:", answer, ss);
}

// Bother the user until they enter a valid integer. Return the integer.
int qInt(const char question[]) {
int resp;
bool fail;
cout << question << ' ';
while (true) {
    cin >> resp;
    fail = cin.fail();
    cin.clear();
    cin.ignore(STRING_SIZE, ' ');
    if (!fail)
      break;
    cout << "Try again: ";
}
return resp;
}

// Bother the user until they enter a positive integer. Return the integer.
int qPInt(const char question[]) {
int response = qInt(question);
while (response <= 0)
    response = qInt("Try again:");
return response;
}

// Get a character from user. Consumes entire line.
char qChar(const char question[]) {
cout << question << ' ';
const char resp = cin.peek();
cin.ignore(STRING_SIZE, ' ');
return resp;
}

// Return whether cs contains c.
bool contains(const char cs[], const char c) {
for (int i = 0; cs[i]; i++)
    if (cs[i] == c)
      return true;
return false;
}

// Bother user until they select an allowed character.
char qSel(const char question[], const char allowed[]) {
char resp = qChar(question);
while (!contains(allowed, resp))
    resp = qChar("Try again:");
return resp;
}

// Bother the user until they enter y or n. Return true for y, false for n.
bool qYN(const char question[]) { return qSel(question, "yn") == 'y'; }

// Bother the user for a path to a real file. Return the open file.
void qFH(const char question[], ifstream& fh) {
char filename[STRING_SIZE];
qCString(question, filename);
fh.open(filename);
while (!fh.is_open()) {
    qCString("Try again:", filename);
    fh.open(filename);
}
}

// End of reusable stuff ------------------------

struct exerciseData {
char name[STRING_SIZE];
char date[STRING_SIZE];
char note[STRING_SIZE];
int time;
int calories;
int maxHeartRate;
};

// Populate an activity from user input.
void queryActivty(exerciseData &ed) {
qGCString("What exercise activity did you do?", ed.name);
qGCString("What was the date (mm/dd/yy):", ed.date);
ed.time = qPInt("How many minutes?");
ed.calories = qPInt("How many calories did you burn?");
ed.maxHeartRate = qPInt("What was you max heart rate?");
qGCString("Do you have any notes to add?", ed.note);
}

// Populate an activity from a line in a csv.
bool parseActivity(exerciseData &ed, ifstream &fh) {
fh.getline(ed.name, STRING_SIZE, ',');
fh.getline(ed.date, STRING_SIZE, ',');
fh.getline(ed.note, STRING_SIZE, ',');
fh >> ed.time;
fh.ignore();
fh >> ed.calories;
fh.ignore();
fh >> ed.maxHeartRate;
fh.ignore();
}

// Load all the data from a csv. Return number of loaded elements.
int loadData(exerciseData eds[LIST_SIZE]) {
int size = 0;
ifstream fh;
qFH("What is the name of the exercise data text file to load?", fh);
while (true) {
    parseActivity(eds[size], fh);
    if (!fh)
      break;
    size++;
    if (size >= LIST_SIZE)
      break;
}
return size;
}

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(17) << name
       << setw(10) << date
       << setw(6) << time
       << setw(10) << calories
       << setw(15) << maxHeartRate
       << setw(12) << note
       << ' ';
}

// Search for specific exercise name. Print all matches.
void search(exerciseData eds[], int count) {
char name[STRING_SIZE];
qGCString("What activity would you like to search for?", name);
cout << "Here are the activities matching " << name << ": ";
showRow("Name", "Date", "Time", "Calories", "Max Heartrate", "Note");
for (int i = 0; i < count; i++)
    if (strcmp(name, eds[i].name) == 0)
      showRow(eds[i].name, eds[i].date, eds[i].time, eds[i].calories, eds[i].maxHeartRate, eds[i].note);
}

// Pretty print all the exercises.
void list(exerciseData eds[], int count) {
showRow("Name", "Date", "Time", "Calories", "Max Heartrate", "Note");
for (int i = 0; i < count; i++)
    showRow(eds[i].name, eds[i].date, eds[i].time, eds[i].calories, eds[i].maxHeartRate, eds[i].note);
}

// Ask user to enter an exercise. Increment count if user chooses to save.
void add(exerciseData eds[], int &count) {
if (count >= LIST_SIZE) {
    cout << "You need to stop exercising. ";
} else {
    queryActivty(eds[count]);
    if (qYN("Record the activity time and calories (y/n)?")) {
      count++;
      cout << "Your activity info has been recorded. ";
    }
}
}

int main() {
exerciseData eds[LIST_SIZE];
int size;

cout << "Welcome to the exercise tracking program. ";
size = loadData(eds);

while (true) {
    const char s = qSel("What would you like to do: (l)ist all, (s)earch by"
                        " name, (a)dd an exercise, or (q)uit? :", "lsaq");
    if (s == 'l') {
      list(eds, size);
    } else if (s == 's') {
      search(eds, size);
    } else if (s == 'a') {
      add(eds, size);
    } else if (s == 'q') {
      break;
    }
};

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

return 0;
}

------------------------------------------------------------------------------
common.cpp
------------------------------------------------------------
#include "common.h"

// Return true if any char in cs satisfies condition.
// condition has type 'int (*condition)(int)' to match <cstring> convention.
bool any(const char cs[], int (*condition)(int)) {
for (int i = 0; cs[i]; i++)
    if (condition(cs[i]))
      return true;
return false;
}

// The q prefix indicates a function that queries the user.

// Ask the user a question. Dump the response into answer.
void qCString(const char question[], char answer[],
          const int ss = strSize) {
cout << question << ' ';
cin.getline(answer, ss);
}

// Bother the user until they enter a string containing graphical characters.
void qGCString(const char question[], char answer[],
           const int ss = strSize) {
qCString(question, answer, ss);
while (!any(answer, isgraph))
    qCString("Try again:", answer, ss);
}

// Bother the user until they enter a valid integer. Return the integer.
int qInt(const char question[]) {
int resp;
bool fail;
cout << question << ' ';
while (true) {
    cin >> resp;
    fail = cin.fail();
    cin.clear();
    cin.ignore(strSize, ' ');
    if (!fail)
      break;
    cout << "Try again: ";
}
return resp;
}

// Bother the user until they enter a positive integer. Return the integer.
int qPInt(const char question[]) {
int response = qInt(question);
while (response <= 0)
    response = qInt("Try again:");
return response;
}

// Get a character from user. Consumes entire line.
char qChar(const char question[]) {
cout << question << ' ';
const char resp = cin.peek();
cin.ignore(strSize, ' ');
return resp;
}

// Return whether cs contains c.
bool contains(const char cs[], const char c) {
for (int i = 0; cs[i]; i++)
    if (cs[i] == c)
      return true;
return false;
}

// Bother user until they select an allowed character.
char qSel(const char question[], const char allowed[]) {
char resp = qChar(question);
while (!contains(allowed, resp))
    resp = qChar("Try again:");
return resp;
}

// Bother the user until they enter y or n. Return true for y, false for n.
bool qYN(const char question[]) { return qSel(question, "yn") == 'y'; }

// Bother the user for a path to a real file. Return the open file.
void qFH(const char question[], ifstream& fh) {
char filename[strSize];
qCString(question, filename);
fh.open(filename);
while (!fh.is_open()) {
    qCString("Try again:", filename);
    fh.open(filename);
}
}
-------------------------------------------------------------------------------
common.h
------------------------------------------
#include <cstring>
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

const int strSize = 256;
const int arraySize = 128;

// Return true if any char in cs satisfies condition.
// condition has type 'int (*condition)(int)' to match <cstring> convention.
bool any(const char cs[], int (*condition)(int));

// The q prefix indicates a function that queries the user.

// Ask the user a question. Dump the response into answer.
void qCString(const char question[], char answer[],
          const int ss = strSize);

// Bother the user until they enter a string containing graphical characters.
void qGCString(const char question[], char answer[],
           const int ss = strSize);

// Bother the user until they enter a valid integer. Return the integer.
int qInt(const char question[]);

// Bother the user until they enter a positive integer. Return the integer.
int qPInt(const char question[]);

// Get a character from user. Consumes entire line.
char qChar(const char question[]);

// Return whether cs contains c.
bool contains(const char cs[], const char c);

// Bother user until they select an allowed character.
char qSel(const char question[], const char allowed[]);

// Bother the user until they enter y or n. Return true for y, false for n.
bool qYN(const char question[]);

// Bother the user for a path to a real file. Return the open file.
void qFH(const char question[], ifstream& fh);
-------------------------------------------------------------------------------
exerciseJournal.cpp
---------------------------------------------------------
#include "exerciseJournal.h"

// struct exerciseData {
//   char name[strSize];
//   char date[strSize];
//   char note[strSize];
//   int time;
//   int calories;
//   int maxHeartRate;
// };

// exerciseData eds[arraySize];
// int countAndIndex;
// char fileName[strSize];

// Populate an activity from a line in a csv.
bool parseActivity(exerciseData &ed, ifstream &fh) {
fh.getline(ed.name, strSize, ',');
fh.getline(ed.date, strSize, ',');
fh.getline(ed.note, strSize, ',');
fh >> ed.time;
fh.ignore();
fh >> ed.calories;
fh.ignore();
fh >> ed.maxHeartRate;
fh.ignore();
}

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(17) << name
       << setw(10) << date
       << setw(6) << time
       << setw(10) << calories
       << setw(15) << maxHeartRate
       << setw(12) << note
       << ' ';
}

// Populate an activity from user input.
void queryActivty(exerciseData &ed) {
qGCString("What exercise activity did you do?", ed.name);
qGCString("What was the date (mm/dd/yy):", ed.date);
ed.time = qPInt("How many minutes?");
ed.calories = qPInt("How many calories did you burn?");
ed.maxHeartRate = qPInt("What was you max heart rate?");
qGCString("Do you have any notes to add?", ed.note);
}

// Load all the data from a csv. Return number of loaded elements.
int exerciseJournal::loadData() {
int countAndIndex = 0;
ifstream fh(fileName);
while (true) {
    parseActivity(eds[countAndIndex], fh);
    if (!fh)
      break;
    countAndIndex++;
    if (countAndIndex >= arraySize)
      break;
}
return size;
}

void exerciseJournal::writeData();

// Ask user to enter an exercise. Increment count if user chooses to save.
void exerciseJournal::add() {
if (countAndIndex >= arraySize) {
    cout << "You need to stop exercising. ";
} else {
    queryActivty(eds[countAndIndex]);
    if (qYN("Record the activity time and calories (y/n)?")) {
      countAndIndex++;
      cout << "Your activity info has been recorded. ";
    }
}
}

// Search for specific exercise name. Print all matches.
bool exerciseJournal::search() {
char name[strSize];
qGCString("What activity would you like to search for?", 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)
      showRow(eds[i].name, eds[i].date, eds[i].time,
          eds[i].calories, eds[i].maxHeartRate, eds[i].note);
}

// Pretty print all the exercises.
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.h
----------------------------------
#include <cstring>
#include <iostream>
#include <fstream>
using namespace std;

const int strSize = 256;
const int arraySize = 128;

struct exerciseData {
char name[strSize];
char date[strSize];
char note[strSize];
int time;
int calories;
int maxHeartRate;
};

class exerciseJournal {
exerciseData eds[arraySize];
int countAndIndex;
char fileName[strSize];
public:
int loadData();
void writeData();
void add();
bool search();
void listAll();
};
-------------------------------------------------
exercise.txt
--------------
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

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote