CSC 161 Grinnell College Spring, 2010
 
Imperative Problem Solving and Data Structures
 

Laboratory Exercise on Characters and Strings

Goals

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

References

This lab assumes that you have access to a C programming language reference, particularly for the C string function library. If you do not have a published reference in paper form, you might consider the following on-line reference:

Steps for this Lab

Lab Outline

  1. Reading Character Input
  2. More Fun with Characters
  3. Some String Basics
  4. Writing String Functions

Part A. Reading Character Input

  1. The reading for this lab describes C functions getc and scanf for reading individual characters.

    1. Review the program reading-chars.c and copy the program to your account. This program contains two sections for reading 5 characters from a terminal; the original program has both of these sections commented out.

    2. Uncomment the section in which reading is performed by the scanf function. Now compile and run the program with these four test cases:

      
      jklmn
      
        j  k  l  m  n
      
      12345abcde
      
      ij
      kl
      m
      

      In each case, explain the output obtained.

    3. Change the "%c%c" to " %c %c" in the first scanf statement. That is, add a space before the %c in two places in the first scanf statement, but not the second. Recompile and rerun the program with the same four test cases. Explain what happens.

      (A careful inspection will reveal an extra space added before each %c in the format string of the first function call. Ordinarily, scanf skips leading whitespace except with the format code "%c"; however, adding a space before "%c" specifically requests that leading whitespace be skipped.)

    4. Put the comments back around the scanf statements, and uncomment the section in which reading is performed by getchar. Compile the program and run it with the above four test cases. Again, explain the output obtained.

  2. Write a short program that repeatedly prompts the user to enter a character and prints that character to the terminal. For this exercise, use the function getchar to read characters. The repetition should stop once the user has entered the character 'q'.

    Does your program behave as you expected? Consider that when you enter a character you must also press Enter before the character is available to your program. At that point, both characters are in the "input buffer". Since your program reads characters one at a time, it will process the desired character, then process the '\n', and then wait for further input from the user.

  3. Consider the program scanf-example.c that uses scanf to read input from the terminal.

    1. Download this program, compile it, and run it with the following input:

      
           This example tests input that
           contains the word done and other words.
           done
      

      (Don't worry if the program stops before you enter the last line — just observe what happens.)

      Explain the output produced.

    2. Change the statement scanf ("%s", a) to gets(a), recompile, rerun with the above 3-line input, and explain the result.

    3. Change the original scanf, this time to fgets(a, 10, stdin), recompile, rerun with the above 3-line input, and again explain what happens.

      To help clarify what happens when you enter the text "done" on the last line, edit the program once more — changing the string comparison to (strcmp (a, "done\n") == 0). Compile and run the program one more time. Can you explain why this experiment yields a different result?

  4. Download the program input-comp.c to your account. Examine this program, noting that string arrays a, b, c have length 8 and are initialized to contain 7 characters (plus the null character at the end). Also, note that in storing arrays a, b, c, the computer will likely store b between a and c.

    1. Run the program, entering the string 012345. Explain what happens.

    2. Run the program, entering the string 0123456789. Explain the output produced.

Part B. More Fun with Characters

  1. Copy and run the two programs from the section on Characters as Integers in today's reading.

    For each program, write a paragraph to explain how the code works.

  2. As you know, strings are arrays of char variables. We could write:

            char myString[] = { 'H', 'e', 'l', 'l', 'o'};
    
    But there is a specialized syntax for initializing strings:
            char yourString[] = "Hello";
    

    Write a program that contains the "declaration-initializations" given above. Then use printf, with the format code %s to print each string.

    Did you get the result you expected? What is different between the two examples?

Part C. Some String Basics

Program string-example.c illustrates several elements of strings in C, including forms of declarations and the string functions strcpy and strstr:

The first several exercises ask you to review the workings of these functions in typical circumstances.

  1. Copy ~walker/c/strings/string-example.c to your account, compile it, and run it, and observe the output.

  2. Explain the initial values printed. Why do several strings have the same values? For example, what is the effect of the line a = s?

  3. Just before the printing of initial values, add the line

    
       s = a;
    

    What happens when you try to compile and run the program? Explain the result. (Restore the original program before continuing with the lab.)

  4. Review the values after modifications, and explain each printed result. (For example, why is the letter 'r' found in strings s and a?)

The printout for Searching results first indicates the base address of the e array. Note that the format %u in the printf statement prints this address as an unsigned integer.

  1. Using the base address of e as the starting point, explain the results printed for the index of 4, e, and X.

  2. In the program, replace the line a[5]='p' by the line a[5]=0. That is, replace 'p' by the number 0. Recompile and rerun the program, and explain the output obtained.

Part D. Writing String Functions

  1. Write a function that accepts a string argument and returns the number of characters (before the null terminator) in the string. Your function header could look like this:

       int myStrlen(const char str[])
    

    Note that "const-qualifying" the parameter as shown here ensures that the function will not modify the string. (If it tries to, the code will not compile.) Thus, it is a simple way to add a safety feature.

    To test your code, add a main function that repeatedly prompts for and accepts words typed at the keyboard. For each word the user types, display the length of the word. Keep processing words until the user types "quit".

    You may want to read the words with something like the following, assuming that you have declared str with sufficient size to hold 20 characters plus the null character.

       scanf("%20s", str);
    

    Recall that you should not use an ampersand before the string name since the name of an array already evaluates to the address of element 0 (the first character in the string).

  2. Write a function propercase(str) that changes the first character of the input string to uppercase and changes the remaining characters to lowercase.

    Your function should use the following header.

       void propercase(char str[])
    

    Notice that the string argument is intentionally not const-qualified. This allows the function to modify the original string, which was declared in the calling function.

    If you want to use the C library functions toupper(ch) and tolower(ch), be sure to include ctype.h.

    Modify your main function to test propercase(str).

Work to turn in:


This document is available on the World Wide Web as

     http://www.cs.grinnell.edu/~walker/courses/161.sp09/lab-strings.shtml

Parts A, B, D: created Fall 2001 for CSC 180 at the University of Toronto by Alan Rosenthal
revised Fall 2002 by Alan Rosenthal (Toronto)
revised Fall 2003, Fall 2004 by Tom Fairgrieve (Toronto)
revised Fall 2004, Fall 2005 by Marge Coahran (Toronto)
revised January 2007 by Marge Coahran (Grinnell) with permission from Alan and Tom
revised February 2007, February 2008 by Marge Coahran
revised February 2009, February 2010 by Henry M. Walker
Valid HTML 4.01! Valid CSS!
Part C: created 21 January 2005 by Henry M. Walker
revised 11 April 2008
Full Lab: revised 13 May 2008 by Henry M. Walker
last revised 22 March 2009 by Henry M.Walker
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.