EEN218 Second Assignment, due Thursday 17th Feb 2000

Write a program that includes three functions, trim(), split(), and main(), as described below. Most of the points are for good clean programming that deserves to work, very few points are available for a nasty unreadable program that just happens to give the right answer when tested.


char *trim(char *s)
This function recevies a string, and should trim (i.e. remove) all "white space" from the beginning and end. White space is any invisible character, including spaces, tabs, enters, escapes, and so forth. Any character with an ascii code less than or equal to 32 my be considered to be white space.
        Your trim() function should not allocate any heap memory (don't use new or malloc). It may modify or re-use the original string, s, in any way you see fit.
        Here is an example showing how trim should behave:
        { char line[100];
          char *tidy;
          printf("input? ");
          fgets(line,99,stdin);
          printf("You typed '%s'.\n", line);
          tidy=trim(line);
          printf("I trimmed it to '%s'.\n", tidy);
When the program is run, imagine that the user presses the following 11 keys: space, space, space, h, e, l, l, o, space, space, enter. The string "line" would contain all 11 characters, which could confuse some processing you perform in the future. The string "tidy" would just contain the five characters h, e, l, l, o. The run would look like this:
        input?    hello  
        You typed '   hello
        '.
        I trimmed it to 'hello'.
Trim is easy, it should not take you long at all. The main part of the assignment is...


int split(char *s, char sep, char *parts[])
Split is used to divide a string up into separate words. The first parameter is the string to be divided; it may contain any number of words, including zero. The second parameter is the character that separates words; normally it will be the space character, but I'm sure you can imaging applications where it would be something else. The third parameter is just an array of string pointers; the pointers will not be properly initialised, all you can rely on is that the array will be big enough.
        The function should scan through the input string, s, searching for appearances of the separator character, sep. Every time a sep character appears, it should start creating a new output string. All of the output strings should be stored in the pointer array, parts. The function should return as its int result the number of output strings that it found.
        Here is a simple example to illustrate its use:
        { char orig[100];
          int i, n;
          char *parts[100];
          strcpy(orig,"The cat sat on the mat");
          n=split(orig,' ',parts);
          printf("The string '%s' contains %d words:\n", orig, n);
          for (i=0; i<n; i+=1)
            printf("part[%d]='%s'\n", i, parts[i]);
          strcpy(orig,"one two three:four five:six seven eight");
          n=split(orig,':',parts);
          printf("The string '%s' contains %d words:\n", orig, n);
          for (i=0; i<n; i+=1)
            printf("part[%d]='%s'\n", i, parts[i]);
The output from running this piece of program would be:
        The string 'The cat sat on the mat' contains 6 words:
        part[0]='The';
        part[1]='cat'
        part[2]='sat'
        part[3]='on'
        part[4]='the'
        part[5]='mat'
        The string 'one two three:four five:six seven eight' contains 3 words:
        part[0]='one two three'
        part[1]='four five'
        part[2]='six seven eight'
You should observe a few things from this example:
        1. There is nothing special about spaces. Only split the string where the specified separator appears.
        2. The user does not supply any space for the sub-strings to be stored, just an array of pointers to point to those strings once they have been created. You must use new or malloc to allocate space for each of the substrings.
        3. The original string is not modified by split(). After calling split, I can still print the original string and see it un-ruined.
        4. There is no way that split can be sure that the array "parts" given to it is big enough. Just assume that the user/caller gets the size right.

Extra Credit
For optional extra credit, make split be clever enough to avoid producing any empty (zero-length) output strings, so that if I tell it to split "hello:there::::mister::bloggs" with ':' as the separator, it would only produce four output strings "hello", "there", "mister", and "bloggs".
        The extra credit part will only be graded if you have done a fairly good job of the main assignment, so don't waste time on it until you are satisfied with everything else.

main()
You may include any extra functions in your submission that you think are useful or necessary. While you are working on the program, of course your main() function can be anything you want. When you are ready to turn in the functions, make your main function be either the following, or something very similar to it, and make sure it still works:
        void main(void)
        { char line[100];
          char *tidy;
          char *parts[100];
          int i, n;
          while (1)
          { printf("? ");
            fgets(line,100,stdin);
            tidy=trim(line);
            n=split(tidy, ' ', parts);
            printf("The string '%s' produced %d parts:\n", tidy, n);
            for (i=0; i<n; i+=1)
              printf("  part %d is '%s'\n", i, parts[i]); } }


Language
For this assignment, you may use plain C (printf, fgets, malloc) or C++ (cin, cout, new) or any combination of the two that works. Beware of mixing printf and cout, or fgets and cin, in the same program; they do interact with each other in unfortunate ways sometimes.