Fall 2012, The College of Saint Rose

Program/Problem Set 2: C Programming
Due: 11:59 PM, Tuesday, September 18, 2012

In this assignment, you will implement some more significant programs in C. Hopefully, none of the tasks will be especially difficult to understand, so you can concentrate on how to implement them in C. That will undoubtedly present plenty of challenges.

You may work alone or with a partner on these tasks. And do not hesitate to ask for help when you get stuck!

You can find and run the executables for my solution code for each program on mogul.strose.edu in /home/cs433/probsets/c/ .

First, we will change the "adder" program from the recent lecture assignment to take its input from the keyboard rather than from the command line. Your program should read in integer values one by one, accumulating a sum as you go, until you encounter an invalid (non-integer) or the end of the input (someone types Ctrl-d). At that point, print out the sum and exit.

There are several ways to read in values from the input, but we will use scanf. Some details about scanf may be found in the class example that computes greatest common denominators.

Hint: you may wish to control your program with a loop that continues as long as your scanf calls continue to report that there was a number successfully matched and stored in a variable.

For one more bit of practice before getting to the somewhat more interesting tasks, extend your input adder program to remember all the values read in by storing them in a dynamically-allocated array. At the end, the program should print the addition problem and its solution in a standard format. For example, given the input values 9, 4, and 5, the program would print

```9+4+5=18
```

Your task here is to be able to create the array and continue to make it larger as needed. Start with a reasonably-sized array (perhaps 10 slots). If the user inputs 10 or fewer values, you are all set. But if an 11th value is input, you will need to resize the array to make space. Use the same strategy as Java's Vector or ArrayList class - double the size of the array each time it fills.

Some things to consider:

• In C, you can allocate a fixed-size array with a declaration such as
```        int a[10];
```

This allocates space for 10 int values on the call stack. However, this array's size must be specified at compile time, and may not be resized. This will not work for our purposes.

• We will want to allocate an array using dynamic memory allocation. This is the same as what Java requires you to do for all arrays, but the syntax is quite different in C, and there is much less error checking done by the system than what you might be used to from Java. To allocate an array of 10 int values in C, you will need to do something like this:
```        int *a = (int *)malloc(10*sizeof(int));
```

This will request from the system enough space to hold 10 values, each the size of an int, and store a pointer to that space in a. We can then use this pointer in the same way we use the name of an array to access its elements, e.g., a[2].

And later in the program when we are done with the memory, we will need to return it to the system:

```        free(a);
```
• When you need to resize, use the realloc function. This function call will do exactly what you need for the doubling of your array size. For example:
```    a = (int *)realloc(a,20*sizeof(int));
```

will replace the pointer a with a new pointer to a chunk of memory now large enough to hold 20 int values, with the original 10 values copied over if needed.

Implementing Some Unix Commands

For the first Program/Problem Set, you implemented 3 Unix commands in a language of your choice. Your task is to reimplement them in C.

Here are the descriptions again:

File Copy

cp filenameA filenameB - copy the contents of filenameA to a file named filenameB; see the Unix cp command.

Write this in a C file cp.c.

Hints:

• Use fopen and fclose to open and close your files.
• Since you want to write everything in the first file to the contents of the second, you may find it easiest to process the file character by character. See getc and putc for input and output of characters, feof for detection of the end of file.
Display File Contents

cat [OPTION] filename - display the contents of filename, where the options can be either (or neither) of:

• -n - number all output lines
• -b - number nonempty output lines

Note: you should not make any assumptions about the maximum length of a single line of the input file. You may wish to write your own function that reads a line from the file into an array you maintain to be the correct length. Your resizeable array from inputadder2 should provide a good model for how to proceed.

Note also that line numbers start at 1. When line numbers are specified, the line number should occupy the first 6 columns and be followed by 2 spaces before the line from the file. A format string conversion specifier of `%6d` in printf will print a number such that it will take 6 characters of output, using spaces to pad on the left if needed (i.e., exactly what you want).

See the Unix cat command.

Write this is a file cat.c.

Word Count

wc filename - find the number of lines, words, and bytes (characters) in filename.

Notes: Your function from cat that reads in a line will likely prove useful here. Look at strsep for a way to separate a string into words by separating on whitespace. Note that blank lines count as a line, but a blank line contributes no words to the total. Also, the new line character at the end of each line should be included in the character count.

See the Unix command wc.

Write this in a file wc.c.

General Requirements

Your code should be commented appropriately throughout. Please also include a longer comment at the top of your program describing your implementation. And, of course, it should include your name.

All of your programs should compile without warnings using gcc on mogul when the -Wall flag is included. This flag turns on extra warnings that will help you avoid some of the pitfalls of C programming. If you encounter any warnings that you don't know how to fix, ask!

Any memory you allocate with malloc or realloc should be returned to the system with a corresponding free call.

Include a Makefile that compiles all 5 programs with the -Wall flag. This Makefile should produce 5 executable programs: inputadder, inputadder2, cp, cat, and wc. My Makefile is on mogul.strose.edu in /home/cs433/probsets/c/ . Please feel free to use or modify as you see fit.

Submission

To submit this assignment, send all necessary files (your 5 C source files and your Makefile) as attachments to terescoj AT strose.edu by 11:59 PM, Tuesday, September 18, 2012.

Please include a meaningful subject line (something like "CS433 Program/Problem Set 2 Submission"). Please do not include any additional files, such as emacs backup files, object files, or executable programs.