MCS273 Introduction to C++ Programming (January 2013)

Logbook query program

Started: Monday, January 14; Due: Friday, January 18, at 9:00 am


This is your first graded lab. You will work on this lab together with a partner, being sure that it accomplishes all of the tasks that I set forth below. You should decide on your teams and inform me on Monday. In grading this lab, I will check for correctness, robustness, documentation, and that you make good usage of procedures. Obviously, your code should compile without warnings.

Your programming tasks

We used to have monitors in our MCS computer lab. When the lab monitors worked, a ``logbook'' program would record the times they worked. That program was the final project for one programming team in MC39 (now MCS270, Object-oriented 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 was certain file formats that conveyed data between them. In this programming, you will write an additional program that would allow 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

would 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.)

You can download a sample data file

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 <
which runs the myHours program with its standard input coming from 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 I will be looking for in your program is that it does appropriate checks for valid input. By this, I mean that it checks for the following:
  • Each input line is of the specified format, with no extraneous space
  • Each starting time precedes the corresponding ending time
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.


Helpful commands

A few commands will help you do error checking:

  1. You can peek at the next character without reading it in char c = cin.peek().
  2. You can find out if a character is a digit using isdigit(c). (You need to #include <ctype.h>
  3. A newline is the character '\n'. (Single quotes denote characters, double quotes are strings.)
  4. You can read (and skip over) the colons by using cin.get(c).
  5. You can detect end of file by first peeking past the end of file and then checking if cin.eof() returns true.
  6. Lazy evaluation of and and or on page 114 will help keep your code clean.

In the gdb debugger you can type
    (gdb) run <
to make gdb redirect input from file


Incidentally, once you've successfully completed this problem, the only minor detail standing in the way of it being a useful addition to the logbook system is getting it to automatically access the real data file, rather than needing input fed to it with <. Although we haven't dealt with 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.

Submitting your code

Use Eclipse to export your project directory to a zip file of the same name as your project (I will go over this in class, and you are welcome to ask me for help on this). Then email me that zip