1. Goals for this week

2. Starting Point Code

Start by creating a week09 directory in your weeklylab subdirectory and copying over some files:

$ cd ~/cs31/weeklylab
$ mkdir week09
$ cd week09
$ pwd
$ cp ~kwebb/public/cs31/week09/* ./
$ ls
Makefile  mylib.c  mylib.h  prog.c  str.c

3. Writing a C library

We are going to learn how to write a C library and how to use it in a program.

First, let’s look at some documentation about libraries in C. We are going to look at the "CREATING AND USING YOUR OWN LIBRARY CODE" section of that document. This content is also available in Section 2.9.6 of the textbook.

Next, lets look at an example C library implementation, starting with the library interface in mylib.h, and the implementation in mylib.c. Open mylib.h and mylib.c in an editor.

Next, open prog.c in an editor: this program uses the mylib library. Let compile and run it.

$ make
$ ./prog

You can read about the phases of compilation, which includes information about the preprocessor and other compilation phases.

4. Strings and chars in C

Let’s look at the file str.c. This code contains some examples of manipulating strings (and individual chars in a string) in C.

In C, a string is a char array with a terminating null character '\0' that signifies the end of the string. The array of chars can be statically or dynamically allocated (by calling malloc). One thing to remember is to allocate enough space for the terminating null character.

Let’s take a look at this code and see what it is doing. Note its uses the ctype and string library functions. C string library functions assume that the caller has allocated space for the result string (note the call to strcpy).

The C string library contains a number of useful functions. In semesters that have the string lab (lab 7), you will write some of them:

strcat, strchr, strcmp, strcpy, strdup, strlen, strstr

The ctype library contains functions for testing char values:

isalnum, isdigit, isspace

Chapter 2.6.3 contains information about the string library and also C library functions for char values.

Their man pages will also give more information about how to use them.

$ man strcmp
$ man isspace

4.1. Try it out

  • In another window, compile and run this program to see what it is doing. Note when it is manipulating the individual char in the string (array of chars) and when it is treating it as a string (using strcpy, strlen).

Try running with some different input strings, for example:

hello 1 2 3
    hello   1   2   3
!@  hello  x%

4.2. Extracting the first token

  • Follow the instructions in the TODO section of the str.c file. Try implementing code to create a substring for the first token in the string you typed in str.c:

    1. Search for the start of the first token (the first non-space char). Save the index of this character in the string in the variable called tok_start.

    2. Continue through the string until you find the end of first token (the first whitespace character after the start of this token). Save the index of this character in the string in the variable called tok_end.

    3. malloc space to hold all of the characters from tok_start up to tok_end, saving a space for the '\0' character.

    4. Copy all of the characters from the original string from tok_start to tok_end into the new string, and be sure to add a '\0' at the end.

    The result should be that the substr pointer points to a string equal to the first token of str. After you’ve extracted this token, print it out.

    Compile and try running with different input strings and see if it works.

5. Dynamically allocated 2-D arrays (an array of arrays)

We are going to look at an example of the "Method 2" way of dynamically allocating a 2D array. This method supports [i][j] indexing, but it is less memory efficient than the single malloc ("Method 1") way of allocating 2D arrays that we used in the Game of Life lab.

This method allocates a 2D array as an array of arrays. In the outer array (of row dimension) each element stores the base address of an inner array ( of column dimension) of values in each row of the 2D array. Section 2.5 of the textbook describes this, and includes an figure of what this version of a 2D array looks like in memory.

This type of 2D array is used for the argv 2D array of char that contains the command line argument values passed as a parameter to main (and as we’ll see in class, the parameter passed to execvp).

In this method, the programmer makes num_rows + 1 calls to malloc:

  1. one malloc to dynamically allocate an array of type * that will store the base address of an array to store each row’s values.

  2. num_rows mallocs to dynamically allocate arrays of type to store the values in each row of the 2D array. The base address of each is stored in the ith bucket of the outer array.

The variable storing the base address of the outer array is a type **: a pointer to a storage location that stores a type * (which stores the base address of an array of type). For example:

int **2d_array;
char **2d_chararr;

6. Parsing the entire command line

Proceed to Lab 8. This is a two-week lab. In the first part of the lab, you’ll be writing a library that parses the command-line arguments into a dynamically allocated two dimensional array.

7. Handy References