CS 222
Program 4
due July 27, 2016

The program

Your program will read a file name from the command line. The file will contain integers. The program will read the file (up to 1000 integers), sort them, then report the integers. The "report" will show each integer once (in the sorted order) along with the number of times that the number appears in the file. For example, if the file numbers.txt has the contents:


2 5 3 99 -8
5 99 99 100 -8
23 -21 3 99 5
running you program will show:

C:\cs222>prog2 numbers.txt
-21  (1)
-8  (2)
2  (1)
3  (2)
5  (3)
23  (1)
99  (4)
100  (1)

Opening and reading files

A file in C is a "stream" represented by a pointer of type FILE * (FILE is defined in the file stdlib.h) and opened with the library function


FILE *fopen(char *filename, "r")
The "r" must be enclosed in double (not single) quotes and indicates that the file is being open for reading. If the file cannot be opened (it may not exist, may be protected, etc.) fopen will return the null pointer. Thus you may open a file with (here name is the name of the file to be opened).

FILE *infile = fopen(name, "r");
if (!infile)
{
   /* the operation was unsuccessful */
   printf("unable to open %s\n", name);
   exit(1);                 /* end the program */
}
You can read the file with fscanf which works just like scanf but takes and extra (first) parameter which is the input stream. The library function

FILE *feof(FILE *stream)
returns a non-zero value if the last attempt to read from the stream read no data but reached the end of file. Thus, a file, infile, of integers can be read by:

int in;
do
{
   fscanf(infile, "%d", &in);   /* read from infile into int variable in */
   if (!feof(infile))           /* only process in if didn't reach end of file */
   {
      /* process in, the last int read, here */
   }
} while (!feof(infile));
fclose(infile);

Sorting an array

You can sort an array with the library function qsort which uses the very efficient quicksort algorithm. It has the rather discouraging prototype:


void qsort(void *base, int n, int size, int (*compare)(const void *, const void *));
Here base is a pointer to the base of the array (usually just the array name), n is the number of elements in the array, size is the size of the type stored in the array, and the fourth parameter compare is a pointer to a function which compares two array elements. compare must take pointers as parameters and must return an int. The return value must be negative if the first parameter precedes the second, positive if the first parameter follows the second, and 0 if they are equal. This function usually takes some awkward type casts. A functiom which will work for us is:

int compare(const void *s, const void *t)
{
   return *(const int *)s - *(const int *)t;
}
Just pass the name of this function as the fourth parameter to qsort.

If you use qsort() you must #include <stdlib.h>.

Counting duplicates

After the user's input has been read into an array and the array has been sorted the duplicates are easy to identify: duplicate values appear grouped together. Some thought is required to do this correctly.

To turn in

You will turn in your well organized and well commented source code and a sample terminal session using an input file which will be provided to you.