CSC 161 | Grinnell College | Spring, 2009 |
Imperative Problem Solving and Data Structures | ||
In this laboratory you will test and strengthen your understanding of strings in C.
Laboratory exercise on characters and strings in C.
You will remember there is a C function fgets(), which can be called as shown below, that reads a line from stdin and copies it into the string dest. Recall that dest is the destination string, maxlen is the length of dest (including space for the null terminator), and stdin should be used verbatim to indicate that input will come from stdin. The function will return NULL when the end of file is encountered. (NULL is another constant declared in stdio.h. Its value is 0, so you can treat it like a boolean.)
while ( fgets(dest, maxlen, stdin) ){ /* do something here */ }
To experiment with this function, write a program that calls fgets repeatedly until the EOF condition is encountered. After reading each line of input with fgets, print the destination string to stdout. Then test the behavior of fgets by entering lines that include some which are shorter and some which are longer than your maxlen value. Do you understand what fgets is doing in each case?
You should have found that fgets will sometimes write the newline character into your destination string. Since this is usually not what you want, write your own function getline() that accepts a destination string and a max length, calls fgets(), removes the newline character (if it exists), and returns 0 when the end of file is encountered. This is a function you may want to keep for future use in the C programs you write.
Write a function piglatin that accepts a destination string and a source string. The source string will be an English word. The function should translate the English word into the associated Pig Latin word, and store the result in the destination string.
Perhaps it has been quite some time (if ever) since you spoke in Pig Latin. The translation rules are as follows.
/* Rules: * - if word begins with a vowel, add "way" to the end * - else find the first vowel, move the consonants before that vowel * to the end of the word, then add "ay" to the end */
For example, if the source string is "scram", the function should return "amscray" in the destination string. If the source string is "apple", the function should return "appleway".
For this exercise, assume that the destination string will be large enough to hold the return value without string overflow. (To be consistent with this, be sure to test your function with word sizes for which it is true!)
Hint: You may find that the C-library functions strcpy(), strcat() and strncat() are useful for this problem.
Write a main program with which to test your function.
Modify your piglatin function so that it uses the C string library safely. In other words, do not make assumptions about the size of the destination string. Instead, your function should ensure that the destination string does not overflow and that it is null terminated upon completion.
The program ~walker/c/strings/string-example2.c declares 5 character arrays and performs several copy operations.
In this program, assume that the variables a and b are stored in successive storage locations, so the b array is stored immediately after the a array. Similarly, assume that arrays d and e are stored in successive locations. Do not assume, however, that the block for a and b is contiguous with the block for c, or that the block for c is contiguous with the block for d and e.
Copy ~walker/c/strings/string-example2.c to your account, compile it, run it, and observe the output.
In the printing after initializations, explain why the string printed for a continues on into the characters for b, but the characters for d and e are as expected.
Can you figure out where array c must be located with respect to a-b and d-e based on the output after the initializations? (Hint: It is located after e. But where exactly?)
Explain the results printed after the final copying section.
The program ~walker/c/strings/string-example3.c contains three string arrays. Assume that the compiler stores these arrays in a contiguous part of memory, but do not assume that str1 is stored first, followed by str2, etc. That is, you should assume that one of these variables is stored first, followed immediately by another variable, and then the third.
Copy ~walker/c/strings/string-example3.c to your account, compile it, and run it. Describe the output briefly in a few sentences.
Change the value of MAX from 27 to 26. Then recompile and run the program. Write a careful explanation of the result. As part of your answer, you may need to determine the ordering of the arrays str1, str2, and str3 in memory; justify your conclusion that these variables are stored in this order.
This document is available on the World Wide Web as
http://www.walker.cs.grinnell.edu/courses/161.sp09/labs/lab-string-puzzles.shtml
Part A: | 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 |
![]() ![]() |
Parts B, C: | created 21 January 2005 by Henry M. Walker revised March 2008 by Marge Coahran revised 11 April 2008 by Henry M. Walker revised 30 December 2009 by Marge Coahran |
|
Full Lab: | revised 13 May 2008 by Henry M. Walker last revised 25 January 2009 by Henry M. Walker | |
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. |