Skip to main content.

Assignment 2: Word Counter in C

Due: before Friday's class.

Objectives: help you create, debug, and extend C programs that run within a shell environment and utilize basic I/O and string manipulation functions.

The scenario

Your well-intentioned-but-inexperienced pair-programming buddy has just written some code for the first assignment. Unfortunately, s/he was abducted by aliens (not again!), and it is now up to you to pick up where s/he left off.

The accompanying program files (Makefile and main.c) contain examples of good and bad programming practices and include deliberate errors. Your job is to find and fix the errors, implement missing features, and learn some tricks of the trade in the process.

Luckily, a test program is included to help you along. You can (and should) use it to check your work. See the Self-Evaluation section for details.

Part 0: Getting the Existing Code/Resources

Copy the entire directory /csdept/courses/cs330/handouts/assign2 into your cs330 directory.

Part 1: Crash Course in C

Read the file review.txt from the directory you just copied. The list of topics is useful for self-assessment and as a study guide.

Answer the questions in 1-Pointers.txt. Identify the key to each problem and keep your answers concise and to the point; 2-3 sentences should suffice. These questions bring up important points about pointer usage in C. Keep these in mind when working on the remainder of the assignment.

Part 2: Fixing the Bugs

The purpose of the provided program is to count words specified as command-line arguments (not quite what you did for assign1). Read the description of the program and its functionality in the comment at the top of main.c. Next, read through the rest of main.c and the Makefile and understand what each part does.

Some topics you may want to review: switch statements, structs, command-line arguments

Compile and run the program from the shell:

> make
> ./main 

(Ignore the warning for now. You will fix this in Part 3.)

The program compiles and links... so it must work, right?! Oh, grasshopper. Is the program really doing what it is supposed to do?

Answer the questions in 2-Debugging.txt and fix the corresponding bugs in main.c. Keep your answers brief and focused.

Part 3: Enhancements

Now that the bugs have been ironed out, it's time to add some functionality to our word counting program.

  1. Alter the program such that only the correct output is sent to the standard output stream (stdout), while error messages are sent to the standard error stream (stderr). Standard Streams in C

    Hint: use fprintf.

    See the expected output listed in the comment at the top of main.c for an example of what should go to stdout.

    Design question: Should the help messages go to stderr or stdout?

  2. Implement an optional command-line switch '-fFILENAME' that sends program output to a file named FILENAME (i.e., filename specified as a command line argument).
  3. Add support for matching arbitrary numbers of words, not just 5. (Hint: use malloc.)
  4. Safeguard the program from buffer overflow attacks. (Hint 1: gets is BAD. Use fgets instead, which specifies the maximum number of characters to be read in.
  5. Allow multiple words to be specified per line. (Hint: Understand strtok.)
    A period on its own line still stops the input.

Self-Evaluation

The testrunner program is included so that you can check your progress as you implement different parts of the assignment.

To run all tests:

> make test

To run a specific test, e.g., stderr_output:

> ./main -test stderr_output

As you can see, testrunner is implemented entirely in C. If you are curious, look at the implementation and see if you can figure out how everything works. The relevant files are: assign2_test.* and testrunner.*.

Note: You should remove or disable any additional debugging output you may have created before running the tests. One way to do this easily is through the use of the preprocessor directive #ifdef, e.g.,

#ifdef DEBUG
fprintf(stderr, "My string %s %d\n", var1, var2);
#endif

Then add -DDEBUG to the CCOPTS line in the Makefile during development, and remove it before testing. Make sure that your code still compiles and runs without the debug output!

FAQ

If my code passes all the tests in testrunner, does that mean that I'll get a 100% on this part of the assignment?

Passing all the tests is a necessary but not sufficient condition to get a 100% on this part of the assignment. You should not only rely on these tests.

Submission

Copy your assign2 directory into your turnin directory, i.e., /csdept/courses/cs330/turnin/yourusername

After copying, check that either:

Note that this does not mean that everyone will be able to read the files. Only you and I should be able to read the files because (1) you are the owner, so you have read permission and (b) the turnin directory is owned by the turnin group, and I am the only member of the turnin group.

Grading (100 pts)

You will be graded on