Spring 2017 CSCI 235 Homework — C file programming 2

This assignment must be uploaded as a .zip or .tar.gz containing a simple appropriate (not NetBeans generated) Makefile and associated C programs to C file programming 2 on moodle by 11:55 PM on December 1. The Makefile must be written to produce an executable program named CollegePrint.

ZIPed NetBeans projects just don’t work and are not appropriate for quality submissions. This time they are forbidden.

The problem

This is an extention of the first C programming assignment, which you should review before reading further.

This assignment requires that you write a program that reads lines of input, from either standard input or a file given on the command line, and produces two output files, both located in the current working directory:

The files

The format of the input file is the same as in the first C programming assignment, a comma separated file with the name, location, and enrollment of a few universities in North Carolina. I am providing a copy of a file unc.txt as an example for you to use in this assignment. (Please reload, because Elizabeth City State University wasn’t in Elizabeth City in the first version.) Do not assume that your solution will be checked only with this sample file. Maybe I’ll add Mars Hill or Warren Wilson!

The text output file should be a neatly formatted printing of the input, sorted by university name. The file cp-out.txt is a sample of the text output. The binary output file contains the same information but is written using the record format described above. The file cp-out.bin is a sample of the binary output. Because this file is not in any standard text format, it may display oddly in your browser. Also, your browser may also try to “fix” the file before storing it on a computer running Windows.

Parsing the command line arguments

When your program is invoked with one or more arguments, such as:
    ./CollegePrint unc.txt
the input of your program should be read from the file given on the command line (argv[1]). If your program is invoked with no arguments, such as:
    ./CollegePrint
the input of your program should be read from standard input.

In both cases, the output files are written to cp-out.txt and cp-out.bin in the current working directory. This is actually a bit simpler that the command argument handling of the starter file.

Your program should not crash when given ”bad“ arguments. Instead it should provide a helpful message.

By the way, the following command, which uses I/O redirection, will automatically connect unc.txt to standard input.
    ./CollegePrint < unc.txt

Getting started

To give everyone similar starting points, I am providing a near-complete solution to the first assignment for starting your work on this assignment. The near-complete solution contains a starter program that illustrates the use of command-line arguments for file and also includes a Makefile which, with minor adjustments, can be used for this assignment.

I am also including a copy of a C program created in the labs on the week of October 16 and 18. This is really a bit more complicated than the program needed for this assignment.

Having the right toolbox

You need access to the GNU toolchain. If you don’t, look at the last section of the course lab page.

Testing your program

Making sure the code compiles clean

Make sure your program in written to the C99 standard and compiles with no warnings using the “pedantic” option of gcc. Using the Makefile provided in the starter file will ensure that these checks are performed.

Making sure command-line arguments are checked

Your program should check that the input file, if given, exists.

rm -f no-file-named-that
./CollegePrint no-file-named-that
  

Your program should check that the input file, if given, is readable.

touch unreadable-file
chmod a-r unreadable-file
./CollegePrint unreadable-file
rm -f unreadable-file
  

Your program should check that the output files can be created.

touch cp-out.txt
chmod a-w cp-out.txt
./CollegePrint
rm -f cp-out.txt
touch cp-bin.txt
chmod a-w cp-bin.txt
./CollegePrint
rm -f cp-bin.txt
  

Making sure the output is correct

Download the file unc.txt for testing your program. When you program is tested with either of the following commands:
    ./CollegePrint < unc.txt
    ./CollegePrint unc.txt
files called cp-out.txt and cp-out.bin should be created.

Viewing the text file

The text file cp-out.txt should be sorted, by university name, and contain neatly formatted columns. It should look a bit like this printout.

Viewing the binary file

The binary file cp-out.bin will look weird when viewed by a conventional text editor or word processor; though you should be able to see the university names and cities. For this, just use cat.
    cat cp-out.bin
You can get an ever better view by using a program designed to display or edit a “hex” file, such as xxd.
    xxd cp-out.bin

However, you still won’t be able to read the binary enrollment field without doing some manual hex conversion. The best check would be to modify the last program presented in the October 16 and 18 labs to display the binary record format used during the lab.

And finally, you can develop some low-level system admin skills by trying out a couple of ancient programs. First, use dd which obeys the ancient command line syntax of IBM JCL. Each record of cp-out.bin is 76 bytes long and the eighth record is for UNC Asheville. Copy the eighth record (after skipping the first seven) with the following command:
    dd if=cp-out.bin skip=7 count=1 bs=76 of=unca.bin
You should now have a 76 byte file called unca.bin . Now use od to look for the individual fields of the record. First, view the first 50 bytes as ASCII characters.
    od -t a -N 50 unca.bin
(Expect to see some null characters at the end.) Next, look at bytes 51 to 70 in ASCII.
    od -t a -j 51 -N 20 unca.bin
Finally, look at the last four bytes as a 32-bit integer. You should see 3821.
    od -t d4 -j 72 unca.bin

Oddly enough, in days long past, students in CSCI 202 were taught how to view binary files.

Turning in your program

Turn in a ZIP file with C programs and a Makefile. Don’t turn in a ZIP of a NetBeans project.