Lab: Strings

This laboratory examines details of string storage, and the operations of string library functions within the C programming language.

To get started, download the starter code for this lab: strings.tar.gz and run the following terminal commands:

$ cd csc161/labs
$ tar xvzf ~/Downloads/strings.tar.gz
$ cd strings
$ code .

The .tar.gz file is a compressed archive that contains multiple files, a bit like the .zip files you may have used on other computers. The files in a .tar.gz archive will generally be contained within a directory, which in this case was named strings.

A. Exploring Memory

Before we get into complex examples, we’ll start by reading and predicting the behavior of code that uses pointers. Open and review string-intro.c.

Exercises

  1. Read through the block of code. Draw a box and arrow diagram to show how the values are stored. Then, write down predictions for what the printf statements will print.
    • Compile and run this code to check your predictions.
    • If you predicted any incorrectly, update your diagram and explain what you missed.
  2. Immediately after the declaration of all arrays, but before any printing, insert the line:
    first[3] = second[3] = third[3] = 0;
    

    This line inserts a null character at index 3 for each of the three strings.

    1. What do you predict will be the output of the modified program?
    2. Verify your prediction: Recompile and rerun the program, describe what (if any) differences result in the output printed, and explain why this output is obtained.
  3. Immediately after the declaration of all arrays, but before any printing, insert the line:
    fifth[3] = 0;
    
    1. What do you predict will happen when you compile and run the program?
    2. Verify your prediction: Recompile and run the program. Why do you think this result occurs?
  4. Leaving the previously added line in, change the declaration of fifth to include the const modifier:
    const char * fifth = "Hello";
    
    1. What do you predict will happen when you try to compile and run the program?
    2. Verify your prediction: Recompile the program. What practice does this suggest programmers should use when declaring strings intended to be immutable?

B. Declaring Strings

Consider the following string declarations.

char *baboon;
char *chimpanzee = "animal";
char dolphin[];
char emu[] = "animal";  
char fox[4] = "animal";
char giraffe[8] = "animal";
char elephant[10];
elephant = "animal";

Exercises

  1. Which declarations are valid? Which are invalid?
  2. How do the valid declarations differ?
  3. What happens if you switch the order of the fox and giraffe declarations? How do you think this can be explained? Think about the bounds of arrays, and the layout of characters in main memory.

C. Initialized and Uninitialized Strings

  • The sizeof operator tells you how much memory the compiler has allocated to something.
  • The strlen function tells you the length of a string, which is the number of characters before you hit the null character ('\0').

Exercises

  1. What do you predict will be the output of the following program?
    char computerscience[16] = "isawesome";
    char isawesome[16] = "computerscience";
    
    printf("strlen (computerscience): %lu\n", strlen (computerscience) );
    printf("strlen (isawesome): %lu\n", strlen (isawesome) );
    
    printf("computerscience: %s\n", computerscience );
    printf("isawesome: %s\n", isawesome );
    
  2. Start a new program for several experiments with strings. Copy the declarations and code above into a main procedure, making sure that you include the library string.h.

  3. Verify your previous prediction by compiling and running your program. Briefly explain why these results are printed.

  4. What would you expect to get if you had instead written:
    char computerscience[16];
    

    instead of:

    char computerscience[16] = "isawesome";
    
  5. Alter the declaration/initialization and verify your prediction by compiling and running the program.
  6. Restore the computerscience[16] initialization and then add this line of code to the end:
    printf("Concatenate the strings: %s", strcat (isawesome, computerscience));
    
    1. What is the result? Is this what you expected?
    2. What do you expect would happen if you changed the bounds of array isawesome to 32?
    3. Compile and run to verify your prediction.
    4. What did the string function strcat() do? Summarize conceptually what happens in the array and where the null character(s) is/are?

D. Passing Strings to Functions

Strings can be passed to a function in a similar way as arrays.

Exercises

In your source file program implement the following function:

/**
 * Revers a string
 * 
 * \param str[] The string to reverse
 */
void
string_reverse (char str[]);

It should reverse the order of the characters in str (except the null character). Note that it will not return a new string, but it will modify the given string.

Note: The function strlen is “expensive” because it must traverse the entire string searching for the null terminator. Thus, your solution should call it at most once.

E. Other string.h functions

The string.h library provides a set of useful functions, among them:

  • strlen(s) returns the length of s
  • strcmp(s,t) returns 0 if two strings are the same, a value smaller than 1 if s<t , and a value greater than 1 if t<s.
  • strcpy(s,t) copies the string t to s.

Exercises

  1. The terminal command man provides helpful information about the standard library C functions.

    1. Go to your terminal and type man string. You will see list of functions available in the string library. Remember that to quit the man pages, you can simply type q.
    2. Go to your terminal and type man strcmp. What are the two different ways that you can compare two strings?
    3. In the same manual page, find what the parameters are for strncmp.
    4. Go to your terminal and type man strcat. What does strcat do? Using what you have learned about how strings are stored, and their null characters, explain how strcat works.
  2. Open and review catstr.c. write down predictions for what the printf statements in –PART 1– will print. Compile and run the program to check your predictions.

    1. Follow the directions in the comments in –PART 2– and fill in the blanks in the code.
    2. What happened in –PART 2– that caused the output to be what we didn’t expect?