This is your first graded lab. You should work on this lab together with a partner, being sure that it accomplishes all of the tasks that we set forth here. In grading this lab, we will check for correctness, robustness, documentation, and that you make good usage of procedures.
When lab monitors work in the computer lab, a ``logbook'' program records the times they work. This program was the final project for one programming team in MC39 (Software development) a few years ago. They actually wrote a collection of several related programs, one for logging in and out, one for printing out the records, etc. The interface between these programs is certain file formats that convey data between them. In this problem, you will write an additional program that allows an MCS lab monitor to determine how many hours he or she has worked so far this month.
There is a file that contains all the data from the month, with one
line per monitoring shift. Each line contains three numbers with
colons between them. The first is the user identification number, or
uid, of the monitor; the second is the starting time; and
the third is the ending time. The times are measured in seconds since
an uninteresting reference point. So, for example, the line
9041:3000:6600would indicate that the monitor with
uid 9041 worked a
shift that lasted for 3600 seconds, i.e., exactly one hour, starting
at time 3000 and ending at time 6600.
What you need to do is read these lines in one by one, until end of
file is reached, and for each check whether the uid is
the one you are looking for. If so, the difference between the start
and end times should be added to a running sum. At the end, this
running sum can be divided by 3600.0 to get the number of hours the
monitor worked, and this can be output.
As described in the book, you can check for end of file by testing
when the input operation, such as cin >> uid, has a false
value. Since the times are quite large, the uid and
start and end times should be input into variables of type
long, and a long should also be used for the
running total time.
One detail is how to know what the uid of the monitor
running the program is; what you can do is put the line
#include <unistd.h>at the top of your program file and then use the
getuid()
procedure to get the uid of the user running the program.
(It'd be most efficient to do this only once, rather than for each
line.)
I have made a sample data file, which is located at:
~mc38/labs/logbook/files/logbook.data
Assuming your program is called myHours and that you are
running it in the directory containing the data, you can use the
< feature of the shell, as in
./myHours < logbook.data
which runs the myHours program with its standard input coming from
logbook.data. Since this is an MCS lab logbook file that
does not contain any of your uids, you are going to have
to figure out what your uid is and insert it at several
places in the datafile. How many hours did you work? (Be sure to
also test your program with inputs simple enough for you to easily
check the answer.)
One thing we will be looking for in your program is that it does appropriate checks for valid input. By this, we mean that it checks for the following:
If your program detects an error on a given line, it should stop processing the line, discard the line, and resume processing on the following line. It should tell the user line number where the error was encountered, and some information about the nature of the error. (Note that additional data or characters anywhere in a line should count as an error, as well as missing data.)
It's best to send errors to cerr rather than
cout:
cerr << "Line 2412: Missing colon\n";
The test input file has no errors; be sure to introduce errors in your short test file to be sure your program is handling errors properly.
char c = cin.peek().
isdigit(c). (You need to #include <ctype.h>
'\n'. (Single quotes
denote characters, double quotes are strings.)
cin.get(c).
cin.eof() returns true.
and and or on page
156 will help keep your code clean.
Note that you need to either include only one of the following:
#include "ccc_ansi.h" // Defines and, or, not #include <string> // You must use &&, ||, !Both define the
string class, so you cannot include
both. If you include the first, don't forget to compiles with
-I/usr/local/lib/cccfiles.
In the gdb debugger you can type
(gdb) run < logbook.datato make
gdb redirect input from file logbook.data.
<.
Although we haven't dealt with this yet this yet, it is a very simple
matter. So, this problem is a good example of the fact that even a
minor amount of custom programming can be useful to someone,
particularly when used together with other existing programs.