CS 3 (Spring 2021) Lab 01: C Strings

This lab focuses on drawing comparisons between Java and C to introduce you to the wild world of C programming.

Setup

If you haven’t already, do the setup (Windows | OS X). Otherwise, just register for the lab using grinch: https://grinch.caltech.edu/register and clone the repository as explained in the setup instructions.

In this lab, we will be writing some functions over C Strings. C Strings can be pretty tricky because of a few “gotchas” which we’ll explore.

Our First Function

The first function you should write is string_print:

void string_print(char *s)

Prints the contents of s, one character per line prefixed with the character’s index (out to two digits) and a colon.


For example, the string “Adam” would appear as:

00: A
01: d
02: a
03: m

To do this, you’ll need to learn about the printf function; you might also find the strlen function useful. Both function names link to our documentation on these functions!

Memory Allocation and C Strings

The next function to write is string_reverse. This one involves creating your own string which means we need to learn how to allocate memory in C.

Allocating Memory in C

In Java, we simply write Object o = new Object() to allocate memory for an Object. In C, we need to call the malloc function and provide the exact size of the allocation we require. This usually looks like Object *o = malloc(sizeof(Object));. There’s a couple of notable pieces of syntax in this line:

Strings in C

In C, strings are extremely primitive. They’re literally an array of bytes. As discussed earlier, pointers and arrays are roughly equivalent. So, the type for a string in C is char *. Notably, pointers have no concept of “length”. So, strings are “null-terminated” meaning after the last character, there is a “null character” (written \0) to indicate the end of the string. A very common mistake in C is not setting the null-terminator or not allocating space for it.

Writing string_reverse

Here’s the specification for the function we want to write. For this one, we’ll walk you through it step by step.

char *string_reverse(char *s)

Returns a new string with the characters in s in the opposite order. Does not edit the original string.


For example, the input string “Adam” would return “madA”.

If all has gone as planned, your output should look something like:

aaaaaaaaaa
bbbbbbbbba

This is not correct. What has gone wrong is we forgot that malloc does not cleanly initialize the contents of memory for us. We need to explicitly set the null-terminator in our string.

Arrays of Strings!

Finally, we’ll implement string_blanks which requires allocating both an array and the elements inside it.

char **string_blanks(char *s)

Returns a new array of strings where each string has a _ in place of one of the characters. Does not edit the original string.


For example, the input string “Adam” would return {"_dam", "A_am", "Ad_m", "Ada_"}.

Recall that, in Java, if I allocate an array like so:

String[] strings = new String[10];

The only thing it does is create 10 spots for Strings. If I want to actually allocate the Strings, I need to separately make and assign them. C is no different.

To create an array of strings, we use the type char ** which means “an array of char *’s. We’ll need to allocate the container first, and then allocate each of the individual strings in the array individually as well. Your code for string_blanks should have two lines that make calls to malloc. Again, remember you can use array notation with pointers. So, array[1][2] would refer to the third character of the second array element.

Getting Checked Off

Lab \(n\) will be due during lab hours for lab \(n+1\). You will need to get manually checked off for most labs as we will not be using totally automated tests. To get checked off, join the office hours queue, and we will get to you as soon as possible.