Characters and Strings

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

Preparation

Like we did when pointers were introduced, you will need to disable ASLR for consistency in the first exercise of the lab.

To start a new shell (the program that actually is running in your Terminal window, listening to and obeying your commands) with ASLR disabled, run the following command in your Terminal:

setarch `uname -m` -R /bin/bash

Exploring Memory

  1. Copy string-intro.c to your account, compile and run it, and then examine the output.
    1. Each run of this program likely places variables in different memory locations. Absolute addresses may change, but do the relative addresses change? That is, to what extent does the memory schematic in the table from the reading need to change for different runs of the program?
    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?

Declaring Strings

  1. Here are a number of different 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";
    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.

Initialized and Uninitialized Strings

  1. Start a new program for several experiments with strings.
    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. 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 initialization given in Step 3a 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?

Control Characters

Certain character values represent actions rather than just a symbol. Here is a short list of what can be done with some characters:

  1. Write a program that:
    • prints out a sentence with tabs in between each word
    • prints out a sentence with vertical tabs between each word
    • illustrates how backspace works (print a word with a few backspace and see how much of the word you can read)

String Functions

  1. Write a function with the following prototype;
    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.

Robots with Strings

  1. Write a program that beeps once for each uppercase letter in the string and twice for each lowercase letter. If a string contains spaces, punctuation, or digits, those characters should not cause beeps. Note: For this program, do not use the function strlen(). Instead, your program should explicitly test for string termination.

String Operators

Remember from the reading on characters and strings that:

  1. The terminal command man provides helpful information about the standard library C functions.
    1. Go to your terminal and type man strcmp. What are the two different ways that you can compare two strings?
    2. In the same manual page, find what the parameters are for strncmp.
    Remember that to quit the man pages, you can simply type q.
  2. Here is a link to the C header file for strings, string.h
    1. What does strcat do? Using what you have learned about how strings are stored, and their null characters, explain how strcat works.
    2. Copy the following catstr.c. Compile and run the program, observing the PART 1 of the output.
    3. Follow the directions in the comments and fill in the blanks in the program.
    4. What happened in part 2 that caused the output to be what we didn't expect? Hint: Think about how strcat works and the null character.

Strings of Music

  1. Write a program that makes the robot beep in the frequencies that corresponds to the musical letters (A,B,C,D,E,F,G - ignore sharps and flats- and H!) that are given in a string. Make the program so that it is not case-sensitive. Here is the header file to define pitches and their corresponding letters: pitches.h.

    Hint: Remember that a string is actually an array.

    For example, give it the word "BED" and play the frequencies for B, E, and D.

  2. Now make this program work for all the letters in the alphabet.

    Suggestion: Use modular arithmetic to wrap the letters back to the musical letters. For example 'H' would wrap to be 'A' ,'I' would wrap to be 'B', 'J' would wrap to be 'C', and so on. (It's not quite the BACH motif, but we can dream.)