CSCI 1730                     Programming Project 2A                  Fall 2008

                             File to Array of Strings


This program is due by midnight on ** Wednesday, June 17 **.

The goal of this project is to introduce you to memory allocation, arrays, and
functions in C.  In part A you will write two source code files,
file2string.c and custout.c.  In part B directory information will be output
in one of several orderings by using the function defined in custout.c.

In file2string.c write a main( ) function in C which reads an input file
(specified by the first command line argument) and copies it byte by byte
into an array of char, which we'll call farray for convenience.  If the input
file doesn't end with a null character, then add an extra null character
at the end of farray.  Your main( ) should also create an array sarray (called
that here for purposes of discussion) of const char* so that sarray gives
the contents of farray as an array of C style (null terminated) strings.
If farray is broken up into exactly k strings by null characters (having
value 0, i.e., equal to the character constant '\0'), then if we concatenate
the strings sarray[0], sarray[1], ..., sarray[k-1] including the null
character at the end of each string then the sequence of characters obtained
is exactly that of farray.  In addition, set sarray[k] = NULL, so that the
array of strings is NULL terminated.  Finally, for testing purposes main( )
should call custout( sarray, flags ) as its last action, where flags is the 
second command line argument or else the null string "" if there is no second
command line argument.

In custout.c write a function custout( ) which returns void and takes two
arguments, of types const char*[] and const char*, in that order.  The first 
argument is assumed to be a NULL terminated array of C style strings, and the
second is assumed to a C style string.  The function call custout(sa, fl) should
write the strings of sa to standard output, one per line, in an order which
is determined by fl.  If fl is the empty string or else not of a proper nonempty
form then the output order should be exactly as in sa.  A proper nonempty form
for fl is "-x" or "-xy" where x is 'f', 'F', 'b', or 'B', and y is 'r' or 'R'.
The significance of f or F is to specify normal string order as provided by
strcmp( ), whereas b or B specifies the opposite order.  In the absence of r or
R strcmp( ) is applied directly to the strings of s.  When r or R is included
then each string must be reversed before applying strcmp( ).  It is permissible,
in fact expected, that sa will be reordered if fl is in one of the proper
nonempty forms.  However do not attempt to reverse the individual original
strings in sa if r or R is present in fl.

For example, suppose ifile is in your working directory and contains the
ten characters 'u', 'a', '\0', '\0', 'Z', '3', 'q', '\0', '6', and  '6', 
in that order.  Then in main farray[0], ..., farray[10] should be assigned the
eleven characters 'u', 'a', '\0', '\0', 'Z', '3', 'q', '\0', '6', '6', and '\0'.
The values of sarray[0], .., sarray[3] should be assigned the addresses of
farray[0], farray[3], farray[4], and farray[8], respectively, and sarray[4]
should be NULL.  When file2string.c is compiled along with custout.c to an
executable file named file2string, the command
{odin} file2string ifile
should result in the following output to the screen:
     ua
     
     Z3q
     66
whereas the command 
{odin} file2string ifile -F
should result in the following output to the screen:

     66
     Z3q
     ua
In the first set of output the second line is blank, corresponding to the
empty string.  In the second set of output it is the first line which is blank.

Your project submission should include an implementation files file2string.c,
custout.c, a Makefile and a READ_ME file.  Your Makefile should compile
the two implementation files to the executable file file2string using gcc.
The "Projects" sub-page contains a link to a sample Makefile of the sort needed.

Some things to note:

  *The names of the files must be followed exactly, so that
   the teaching assistant and the instructor can test your project
   without editing your code.

  *All file I/O must be done using the routines described in chapter 3
   of the UNIX text.

  *Dynamic memory allocation in C can be done with malloc( ) and free( ).
   These are declared in <stdlib.h>; in the UNIX text there is an example
   showing how to use them in Figure 2.15, and a description in Section 7.8.

  *For putting the elements of an array in order you can use qsort( ),
   which is also declared in <stdlib.h>.  Type "man qsort" on atlas and odin
   for the prototype and different examples of how to use qsort( ).
   The example on odin's man page shows how to enclose strcmp( ) in a wrapper
   which can be passed to qsort( ) as the comparison function.
   The declaration for strcmp( ) is in <string.h>.

  *Test your file2string program on text files of various sorts.  Note that
   you'll need to write your own files using write( ) and buffers containing
   the null character in order to create files which break into multiple
   strings.  Normal text editors don't allow you to insert null characters.

  *The program should be robust and include appropriate error checks.  For
   instance, if in one of the sample commmands above ifile already exists
   then an error message should be issued; if it does exist, file named ifile
   should not be removed or altered.

  *The submission procedure and requirements common to all projects are
   described on a separate page which is linked from the course "projects"
   sub-page.  Follow the submission procedure carefully.

  *A project which does not compile on odin using gcc for GCC 4.1.2 will
   score 0.  Projects which do compile properly will be scored out of 100
   (if on time) based on (1) correctness of operation, (2) quality of design,
   (3) coding style and documentation of the source code, and (4) correctness
   and usefulness of the READ_ME file and the Makefile.