Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

This assignment has all of the functionality of assignment 3, but will be rewritten to use dynamic c-strings and dynamic structs. Dynamic memory can leak,

This assignment has all of the functionality of assignment 3, but will be rewritten to use dynamic c-strings and dynamic structs. Dynamic memory can leak, so use Valgrind to check your code for leaks (see below). In addition to the methods listed in project 3, you will create one more method to calculate the total calories burned for all exercises in the database. So, this assignment will have the same user- controlled loop as assignment 3 plus the total option. The menu items are: search for an exercise by name, list all exercises stored in memory, add a new exercise, print the total calories burned for all exercises in memory, or quit. Just like assignment 3, your program will write the data back to the same file as the input file at program termination, using the writeData() method. Dont forget to make a backup copy of assignment 3 before modifying the source code for assignment 4.

image text in transcribed

image text in transcribed

--------------------------------------------------------------------------------

Here are Project 3 files below

-----------------------------------------------------------------------------

// common.cpp

#include "common.h"

// Return true if any char in cs satisfies condition. // condition has type 'int (*condition)(int)' to match 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) { cout

// Bother the user until they enter a string containing graphical characters. void qGCString(const char question[], char answer[], const int ss) { 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 > resp; fail = cin.fail(); cin.clear(); cin.ignore(strSize, ' '); if (!fail) break; cout

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

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

// 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); } }

// Bother the user for a path to a real file. Set fn to filename. void qFN(const char question[], char fn[], const int ss) { ifstream fh; qCString(question, fn); fh.open(fn); while (!fh.is_open()) { qCString("Try again:", fn, ss); fh.open(fn); } }

-------------------------------------------------------------------

// common.h

#ifndef _COMMON_H_ #define _COMMON_H_

#include #include #include #include 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 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);

// Bother the user for a path to a real file. Set fn to filename. void qFN(const char question[], char fn[], const int ss = strSize);

#endif

--------------------------------------------------------------------

// exercise.cpp

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 1,1,1,1,1,1

------------------------------------------------------------------------------

// exerciseJournal.cpp

#include "exerciseJournal.h"

// 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 void showRow(A name, B date, C time, D calories, E maxHeartRate, F note) { cout

// 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); }

// Ask the user which file to load. Set fileName. void exerciseJournal::queryFilename() { qFN("What is the name of the exercise data text file to load?", fileName); }

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

void exerciseJournal::writeData() { ofstream of(fileName); if (of.is_open()) for (int i = 0; i

// Ask user to enter an exercise. Increment count if user chooses to save. void exerciseJournal::add() { if (countAndIndex >= arraySize) { cout

// 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

// Pretty print all the exercises. void exerciseJournal::listAll() { showRow("Name", "Date", "Time", "Calories", "Max Heartrate", "Note"); for (int i = 0; i

--------------------------------------------------------------------

//exerciseJournal.h

#ifndef _EXERCISE_JOURNAL_H_ #define _EXERCISE_JOURNAL_H_

#include "common.h" #include #include #include using namespace std;

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: void queryFilename(); int loadData(); void writeData(); void add(); bool search(); void listAll(); };

#endif

----------------------------------------------------------------

// main.cpp

#include "common.h" #include "exerciseJournal.h" #include using namespace std;

int main() { exerciseJournal journal; cout Programming Requirements For assignment 3, our exercise Data struct used c-strings that were a constant size, as you can see from the version 3 struct to the left. But this kind of storage wastes a lot of memory. In order to hold an exercise that has a long name or note, strSize // Project 3 Version struct exerciseDataneeded to be fairly large. Let's use an // Project 4 Version struct exerciseData char name [strSize]; char date[strSize]; char note[strSize]; int time int calories; int maxHeartRate example "Great Workout", which might be a note for one of the exercises. This c-string only has 13 characters. Suppose you set up strSize to be 128. Then 115 bytes are wasted, because we set them aside but didn't use them. So, for assignment 4, we Ji will be replacing the c-strings with char char* name; char date char * note; int time int calories; int maxHeartRate; pointers, as you can see in the project 4 version on the right. This will allow us to set aside just the right amount of space for each c-string item. The main differences in the implementation file will be in loadData) and add(), because these are the two methods that store data in memory. So, you will need similar strategies for both methods we would like to set aside just the right amount of storage, but the problem is, we don't know how long each c-string is until we load it from the file or ask the user for the information. So the simplest way to solve this problem is to create local temporary storage: char temp [strSize]; Now you are free to use istream.getline (temp, strSize); to load data, just like with assignment 3. Then you can find out how long the c-string is by calling strlen(): int len; len = strlen (temp): Now you can pass len along to the 'new' operator: exercises [i].name = new char [1en + 11: Notice that l used len + 1 inside of the square brackets. This is so there will be room for the null terminator. The last step is to copy the string from temp over to the brand new dynamically allocated c-string: strcpy (exercises[i].name, temp); Continue to place your implementation and main function code into separate source code files, and include a header file in both source code files. You must have at least 2 source code files, but you may have more if you wish class exerciseJournal exerciseDataexercises [arraySize]; int countAndIndex; char fileName[strSize]; public: int loadDataO; void writeDataO; void addO bool search); void listAllO ~exerciseJournalO; l

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions

Question

What is the environment we are trying to create?

Answered: 1 week ago

Question

How can we visually describe our goals?

Answered: 1 week ago