Objectives

  • To practice creating and using records/structures in C.
  • To practice using and creating arrays of records.
  • To practice using FILE I/O.
  • To practice developing functions to work with array data.
  • To practice writing functions with output parameters (using pointers).

Orientation...

This lab will involve developing a small C program which handles data for a running "log book". You will be creating your own type, a record/structure, in order to store the run information used by the running log. You will need to develop a variety of functions to process this data. (Note that part of this lab is intended to help you practice using output parameters (pointers), so all of your functions should be void functions.) Read this entire lab before you begin working.

Part 0: Creating the data type and reading in data...

Start out by defining a structure to store run data. This structure must be named Run and must include:

  • The name of the run (20 character maximum)
  • The distance of the run in miles
  • The PR (personal record) for the run in seconds.
  • The number of times the run has been done.

The lab8shell.c file will compile once you define your Run structure. Note that you will need to name the fields in your structure to match those used in the shell file (name, distance, prSec, and count, respectively) in order for the file to compile. Your other option is to modify the identifiers used in the shell file accordingly.

You will also be writing a variety of functions which operate on the run data. You will read an initial 'run' database from file, however, every time the user goes for a run, the program data must change to reflect this. The run database will hold at most 30 different runs.

Write the appropriate code to parse the run data from an input file named run.data and store it in your internal data structure. This function must populate your array of runs and return the number of runs read from the file (either via the return value or an output parameter). You must develop this entire function yourself. You are not given a prototype to work from.

Note that the strings representing the run names have underscores instead of spaces in them. This program will be much more difficult if you try to implement it with strings that have spaces in them. Use an underscore whenever you mean to put a space in the run name.

good: los_osos_loop

bad: los osos loop

Part 1: Creating a function to print the data...

Write a funcion to print out the run data. The print function should use the PR seconds to print the PR time in hours, minutes, and seconds. Additionally, it should use the PR seconds and distance to compute the PR mile pace. (Note that the pace does not print hours because it is highly unusual for a runner to take a runner longer than 59 minutes to run a mile.) The initial input should print out as follows:

Name Distance PR Pace Count
------------------------------------------------------
diablo_loop 1.00 0:08:52 8:52 12
madonna 6.20 1:07:30 10:53 7
perfumo_canyon 11.40 1:55:45 10:09 2
los_osos_loop 4.50 0:42:30 9:26 3

Remember to make this a void function.

void displayRuns(Run r[], /* input - run list */
int numRuns); /* input - number of runs in the list */

In order to print the PR and Pace, you need to use a function that will convert seconds to hours, minutes, and seconds. The function takes the total seconds as an input paramenter and hours, minutes, and seconds as output paramters. This function is in the given shell file, but you need to complete it.

void secsToHMS(int totalSecs, /* input - total seconds */
int *h, /* output - hours */
int *m, /* output - minutes */
int *s); /* output - seconds */

Part 2: Creating a function to add a run to the list...

Next you will be writing a function to edit the run list. There are two possible ways to edit the list. Either the user will add a new run to the list or update an existing run.

void addRun(Run r[], /* input - run list */
int *numRuns); /* input/output - number of runs in the list */

First, prompt the user for the name of the run. Then call a function findRun to determine if the run is already in the database: It takes the array of run data, the current number of runs in the list, and the run to search for as input parameters. It takes the index location were the run is found as an output parameter. The function sets the index to the position in the list of the target run or a -1 if the run is not found. This function is written for you.

void findRun(Run r[], /* input - run list */
int numRuns, /* input - number of runs in the list */
char name[], /* input - run to search for */
int *index); /* output - position of found run */

If the run is not in the list...

  • Set the name of the run in the next available spot in the list.
  • Get the distance in miles.
  • Get the time the user took to do the run in hours, minutes, and seconds. Convert that to seconds and set the PR seconds for the run. Note that whatever time the user enters will be the PR since it is the first time the run is done.
  • Set the count for the run to one.
  • Increment the number of runs in the list.

If the run exists in the list...

  • Prompt the user for the time it took for them to complete the run. Check to see if this time is less than the PR time and update the PR accordingly.
  • Increment the count for the current run. (Do not increment the number of runs in the list since no new run was added.)

Each time the database is updated, please print it out again.

Part 3: Saving the data back to the data.txt file...

A database is useless if the data is not saved between runs of the program. You will call a function to write the run list out to the run.data file before the user quits the program. This function is written for you.

void writeFile(Run r[], /* input - run list */
int numRuns); /* input - number of runs in the list */

Part 4: Create a main function to drive your program...

Create a main function to orchestrate how your program runs. It would be useful to work on this function as you write the above functions to test your work.

Using the functions above, this function should...

  • declare the array of runs to hold the run list,
  • read the data from the file into the array,
  • display the intial run list,
  • in a loop, prompt the user for whether they would like to add a run or quit,
  • write the data to a file if the user chooses to quit and display "Happy trails!"

The following is an example run. The user input is in bold for illustration only. Also note that the % sign is an example prompt on hornet. Do not print the %.

% a.out

Run Report:

Name Distance PR Pace Count
------------------------------------------------------
diablo_loop 1.00 0:08:52 8:52 12
madonna 6.20 1:07:30 10:53 7
perfumo_canyon 11.40 1:55:45 10:09 2
los_osos_loop 4.50 0:42:30 9:26 3
(a)dd run or (q)uit: a

Run Name: madonna
Time (hh mm ss): 1 10 45

Run Report:

Name Distance PR Pace Count
------------------------------------------------------
diablo_loop 1.00 0:08:52 8:52 12
madonna 6.20 1:07:30 10:53 8
perfumo_canyon 11.40 1:55:45 10:09 2
los_osos_loop 4.50 0:42:30 9:26 3
(a)dd run or (q)uit: a

Run Name: los_osos_loop
Time (hh mm ss): 0 41 23

Run Report:

Name Distance PR Pace Count
------------------------------------------------------
diablo_loop 1.00 0:08:52 8:52 12
madonna 6.20 1:07:30 10:53 8
perfumo_canyon 11.40 1:55:45 10:09 2
los_osos_loop 4.50 0:41:23 9:11 4
(a)dd run or (q)uit: a

Run Name: dog_park
Distance in Miles: 2.3
Time (hh mm ss): 0 22 10

Run Report:

Name Distance PR Pace Count
------------------------------------------------------
diablo_loop 1.00 0:08:52 8:52 12
madonna 6.20 1:07:30 10:53 8
perfumo_canyon 11.40 1:55:45 10:09 2
los_osos_loop 4.50 0:41:23 9:11 4
dog_park 2.30 0:22:10 9:38 1
(a)dd run or (q)uit: q

Happy trails!
% a.out

Run Report:

Name Distance PR Pace Count
------------------------------------------------------
diablo_loop 1.00 0:08:52 8:52 12
madonna 6.20 1:07:30 10:53 8
perfumo_canyon 11.40 1:55:45 10:09 2
los_osos_loop 4.50 0:41:23 9:11 4
dog_park 2.30 0:22:10 9:38 1
(a)dd run or (q)uit: q

Happy trails!

Part 5: Handing in Your Source Electronically...

handin graderjw Lab08 lab8.c
Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.