| CSC 161 | Grinnell College | Spring, 2015 |
| Imperative Problem Solving and Data Structures | ||
This laboratory exercise examines characters, details of string storage, and the operations of string library functions within the C programming language.
Program string-intro.c shows several variations related to the declaration of character arrays, strings, and char * variables.
One run of this program produced the following output:
first 3 characters in each array first: Col second: Wor third: Com fourth: Wor fifth: Hel Variable addresses and array base addresses first address: 359157264, array base address: 359157264 second address: 359157248, array base address: 359157248 third address: 359157232, array base address: 359157232 fourth address: 359157224, array base address: 359157248 fifth address: 359157216, array base address: 4196464 variables printed as strings first: Cold\ufffd second: World third: Computer ScienceWorld fourth: World fifth: Hello
Understanding this program and output can provide substantial insights to how C works with arrays, characters, strings, and pointers.
The right column shows (in extreme detail) the allocation of memory for program string-intro.c, based upon the above run. Starting at the top of the program:
The first set of printf statements access the first three characters in each character array. Within a printf statement, the %c format prints exactly one data element as a character, so that three characters are printed for each printf statement here. Note that arrays and subscripts work the same whether the variable is declared as an array or as the base address of an array found elsewhere.
The second set of printf statements display where each variable is mapped in main memory. The output shown above maps to the memory schematic on the right.
The third set of printf statements print data as C strings. In C, a string variable identifies a starting or base address, and the string is considered to continue until a code 0 or null character is encountered.
| variable | value stored | memory address |
|---|---|---|
|
section of memory for literal strings | H | 4196464 |
| e | 4196465 | |
| l | 4196466 | |
| l | 4196467 | |
| o | 4196468 | |
| \0 (number) | 4196469 | |
| … | ||
| fifth |
integer value 4196464 | 359157216 |
| 359157217 | ||
| 359157218 | ||
| 359157219 | ||
| 359157220 | ||
| 359157221 | ||
| 359157222 | ||
| 359157223 | ||
| fourth |
integer value 359157248 | 359157224 |
| 359157225 | ||
| 359157226 | ||
| 359157227 | ||
| 359157228 | ||
| 359157229 | ||
| 359157230 | ||
| 359157231 | ||
| third | C | 359157232 |
| o | 359157233 | |
| m | 359157234 | |
| p | 359157235 | |
| u | 359157236 | |
| t | 359157237 | |
| e | 359157238 | |
| r | 359157239 | |
| <space> | 359157240 | |
| S | 359157241 | |
| c | 359157242 | |
| i | 359157243 | |
| e | 359157244 | |
| n | 359157245 | |
| c | 359157246 | |
| e | 359157247 | |
| second | W | 359157248 |
| o | 359157249 | |
| r | 359157250 | |
| l | 359157251 | |
| d | 359157252 | |
| \0 (number) | 359157253 | |
| not specified | 359157254 | |
| not specified | 359157255 | |
| not specified | 359157256 | |
| not specified | 359157257 | |
| not specified | 359157258 | |
| not specified | 359157259 | |
| not specified | 359157260 | |
| not specified | 359157261 | |
| not specified | 359157262 | |
| not specified | 359157263 | |
| first | C | 359157264 |
| o | 359157265 | |
| l | 359157266 | |
| d | 359157267 | |
| not specified | 359157268 | |
| not specified | 359157269 | |
| … | ||
Copy string-intro.c to your account, compile and run it, and examine the output.
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.
Recompile and rerun the program, describe what (if any) differences result in the output printed, and explain why this output is obtained.
Immediately after the declaration of all arrays, but before any printing, insert the line:
fifth[3] = 0;
What happens when you try to compile and run this program? Why do you think this result occurs?
char *baboon; char *chimpanzee = "animal"; char dolphin[]; char emu[] = "animal"; char fox[4] = "animal"; char giraffe[8] = "animal"; char elephant[10]; elephant = "animal";
Start a new program for several experiments with strings.
Copy the following declaration and code into a main procedure, making sure that you include the library string.h:
char computerscience[16] = "isawesome";
char isawesome[16] = "computerscience";
printf ("strlen (computerscience): %d\n", strlen (computerscience) );
printf ("strlen (isawesome): %d\n", strlen (isawesome) );
printf ("computerscience: %s\n", computerscience );
printf ("isawesome: %s\n", isawesome );
What output is obtained? Briefly explain why these results are printed.
What would you expect to get if you had written:
char computerscience[16];
instead of:
char computerscience[16] = "isawesome";
Run the program to check whether your expectations match what is printed.
Restore the initialization in Step 3a and then add this line of code:
printf ("Concatenate the strings: %s", strcat (isawesome, computerscience));
From the reading you have done on Characters and Strings, you have read that char is actually considered to be a type of integer. We can use this property of chars to do integer arithmetic on their values. Every char has a corresponding integer. As you know, we can find out what these values are from an ASCII table.
Write a program that will take the given hard-coded character, and print out the character and its corresponding integer value in this example format:
'A' = 65
Hint: Since characters are integers, you need to only use %d to print the integer.
Write a program that takes the name of the robot by using rGetName(), converts all the characters of the name to uppercase (use the string function toupper, if you wish), and then sets the robot's name to the uppercase version, using rSetName().
Keep in mind that the value of a character is represented by putting single quotes, and string is represented by double quotes.
Characters can represent actions rather than just printing a symbol. Here is a short list of what can be done with some characters:
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.
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.
For this program, do not use the string operator strlen().
Remember from the reading on characters and strings that:
The terminal command man can provide helpful information about the standard C functions.
Go to your terminal and type man strcmp. What are the two different ways that you can compare two strings?
In the same manual page, find what the parameters are for strncmp.
Remember that to quit the man pages, you can simple type q.
Here is a link to the C header file for strings, string.h
What does strcat do? Using what you have learned about how strings are stored, and their null characters, explain how strcat works.
Copy the following program; catstr.c. Run the program and observe the PART 1 of the output.
Follow the directions in the comments and fill in the blanks in the program.
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.
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 Remember that a string is actually an array.
For example, give it the word "BED" and play the frequencies for B, E, and D.
Now make this program work for all the letters in the alphabet. Hint: Use mod 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.
Development of laboratory exercises is an iteractive process. Prof. Walker welcomes your feedback! Feel free to talk to him during class or stop by his office.