| CSC 201 | Grinnell College | Spring, 2005 |
| Data Representation, Memory Management, and Formal Methods | ||
This laboratory exercise examines details of string storage and the operations of string library functions within the C programming language.
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:
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.
Copy ~walker/c/strings/string-example.c to your account, compile it, and run it, and observe the output.
Explain the initial values printed. Why do several strings have the same values? For example, what is the effect of the line a = s?
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.)
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.
Using the base address of e as the starting point, explain the results printed for the index of 4, e, and X.
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.
Program 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 location of the b array is immediately after the a array. Similarly, assume that arrays c, d, and e are stored in successive locations. You should not assume, however, that the block for a and b is contiguous with the block for c, d, and e.
Copy ~walker/c/strings/string-example2.c to your account, compile it, and 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 the other variables are as expected.
Explain the results printed after the final copying section.
Program 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.
The next several parts of this lab are designed to solve the problem of reading successive lines of words from the keyboard, ordering the words from those lines within a doubly-linked list, counting the number of times each word occurs, and printing the distinct words and their counts. The following provides a guide to accomplish this task, although you are not required to complete these steps in the order given. That is, only the final program of this section need be submitted.
Throughout this work, you may assume that any input contains only
Write a program that reads a line from the keyboard, converts all letters to lower case, separates the line into words, and prints the words on separate lines.
Hint: The following possible outline draws heavily on
Eric Huss, The C
Library Reference, 1997.
Use fgets (section 2.12.5.2) to read a line.
Write a simple loop with tolower (section 2.2.1) to convert letters to lower case.
Use strtok (section 2.14.22) to obtain words on the line, separated by whitespace. (Note that this is much simpler than the extended example given in section 2.14.22, since you can print a string as soon as it is obtained; it need not be placed into an array.) Alternatively, you may want to use strtok, following the example discussed in class.
Enclose the processing of step 12 within a loop that continues until the user enters the word "stop" on a line by itself.
Consider a doubly-linked list with the following node structure:
/* Maximum length of names */
#define strMax 20
struct node
{ char word [strMax];
int count;
struct node * prev;
struct node * next;
};
Here, the word field will store a character string, and the count field will keep track of the number of times that the word string has been encountered.
Adjust your work from the doubly-linked list lab, so that the insertion procedure works as follows:
The insertion procedure keeps words in alphabetical order (so you do not need to indicate where successive items will be placed).
If a new word is not already found on the list, then the word is inserted in a new node with a count of 1.
If a word is found to be already on the list, then no new node is inserted, but the count of the relevant word node is increased by 1.
For practice with doubly-linked lists, be sure your insert procedure has the following signature:
void insert (struct node ** firstPtr, struct node ** lastPtr, char * wordStr)
In traversing the linked list to find the word, your code should be as simple as possible. For example, you need only one temporary pointer to keep track of the location on the list; a prev pointer is not needed for doubly-linked lists.
Combine the doubly-linked list procedures of part 14 with the reading of words from step 13. Thus, instead of printing a word as it is identified, the main reading loop will insert the word into the list.
Use int strcmp(const char *str1, const char *str2) (Section 2.14.10) to determine if the new word comes before the string in a node or if the new word matches the string in a node.
Use strcpy (Section 2.14.13) or strncpy (Section 2.14.14) when copying the word to the relevant field within a node.
When all words are entered (until the line "stop"), the program should print the words and their counts in reverse alphabetical order.
This document is available on the World Wide Web as
http://www.cs.grinnell.edu/~walker/courses/201.sp05/lab-strings.shtml
|
created January 21, 2005 last revised April 8, 2005 |
|
| For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. |