We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

C Strings

Since the beginning of the course we've been doing these shenanigans to be able to print strings:

char *msg = "ssh terminal.shop for the best coffee";

I told you not to worry about the weird char * syntax, but now that we understand a bit about pointers, let's dive into it. In the example above, msg is a pointer to the first character of the string "ssh terminal.shop for the best coffee", which is a C string. C strings are:

  • How we represent text in C programs
  • Any number of characters (chars) terminated by a null character ('\0').
  • A pointer to the first element of a character array.

It's important to understand that most string manipulation in C is done using pointers to move around the array and the null terminator is critical for determining the end of the string. In the example above, the string "ssh terminal.shop for the best coffee" is stored in memory as an array of characters, and the null terminator '\0' is automatically added at the end.

C Strings Are Simple

  • Unlike other programming languages, C strings do not store their length.
  • The length of a C string is determined by the position of the null terminator ('\0').
  • Functions like strlen calculate the length of a string by iterating through the characters until the null terminator is encountered.
  • This lack of length storage requires careful management to avoid issues such as buffer overflows and off-by-one errors during string operations.

Pointers vs. Arrays

You can declare strings in C using either arrays or pointers:

char str1[] = "Hi";
char *str2 = "Snek";
printf("%s %s\n", str1, str2);
// Output: Hi Snek

The output is the same. Let's break down the memory of this example:

// notice we aren't using all 50 characters
char first[50] = "Snek";
char *second = "lang!";
strcat(first, second);
printf("Hello, %s\n", first);
// Output: Hello, Sneklang!

The strcat function appends its second argument to the first argument. In this case, it appends "lang!" to "Snek", resulting in the output Hello, Sneklang!.

Here's what first might look like in memory:

The \0 is a \ followed by the number zero. Do not confuse it with the O letter.

'S' 'n' 'e' 'k' '\0' ???? ... ????
0x3000 0x3001 0x3002 0x3003 0x3004 0x3005 ... 0x3031

NOTE! There is a bunch of garbage memory after the end of the string.

Here's what second might look like in memory:

'l' 'a' 'n' 'g' '!' '\0'
0x4000 0x4001 0x4002 0x4003 0x4004 0x4005

And first after strcat:

'S' 'n' 'e' 'k' 'l' 'a' 'n' 'g' '!' '\0' ???? ... ????
0x3000 0x3001 0x3002 0x3003 0x3004 0x3005 0x3006 0x3007 0x3008 0x3009 0x300A ... 0x3031

The strcat function appends the string "lang!" to the end of the string "Snek", but smartly uses the null terminator to know where to start appending. It doesn't know the length of the string, but it knows where it ends.

Assignment

At Sneklang, we have a bit of "not invented here" culture. As such, we've decided to implement our own string concatenation function.

Complete the concat_strings function. It should append str2 to the end of str1 in place. Here are the steps:

Don't cheat and use strcat!

str1 is already allocated with enough memory to hold the concatenated string, so don't worry about that.

Tips

  • Use a while loop and a pointer dereference to see when you reach a null terminator.
  • Increment your pointer with the ++ operator to move to the next character.
  • You can copy a character by dereferencing and assigning the value of one pointer to another.