Strings are char arrays

C has no real string type. A "string" is just an array of char with one rule: it ends with a zero byte, written '\0'. That terminator is how every string function knows where the text stops.

char name[] = "Ada";

This creates a 4-byte array, not 3:

index:  [0]   [1]   [2]   [3]
char:   'A'   'd'   'a'   '\0'
byte:    65   100    97     0

Yes, characters are numbers. 'A' is just 65 in ASCII, and %c prints the character while %d prints its number. That means you can do arithmetic on letters: 'a' - 'A' is 32, the gap between lowercase and uppercase.

The standard function strlen (from <string.h>) counts the characters before the '\0'. There is no stored length anywhere; it really walks the array until it hits zero. So strlen("Ada") is 3 while sizeof(name) is 4.

This design is simple and cheap, and also the source of decades of bugs. If the '\0' is missing, functions like strlen and printf("%s") keep reading past the end of the array into whatever memory follows: undefined behaviour again. Always leave room for the terminator when you size a char array yourself.

One more trap: char *s = "hi"; points at a string literal, which you must not modify (undefined behaviour). char s[] = "hi"; makes your own copy in an array, which you can change freely.

Try it yourself

Edit it. Break it. Run it again.
#include <stdio.h>
#include <string.h>

int main(void) {
    char word[] = "Hi!";
    printf("strlen says %zu, sizeof says %zu\n", strlen(word), sizeof(word));
    for (int i = 0; i < (int)sizeof(word); i++) {
        printf("word[%d] = %d", i, word[i]);
        if (word[i] != '\0') {
            printf(" ('%c')", word[i]);
        }
        printf("\n");
    }
    return 0;
}
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

Your turn

Type it yourself. That is the whole trick.

1strlen by hand

Finish int my_strlen(char s[]) so it counts characters until it reaches '\0', without using <string.h>. The program should print:

  • 5
  • 0
  • 13
#include <stdio.h>

int my_strlen(char s[]) {
    int n = 0;
    return n;
}

int main(void) {
    printf("%d\n", my_strlen("hello"));
    printf("%d\n", my_strlen(""));
    printf("%d\n", my_strlen("pointers soon"));
    return 0;
}
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

2SHOUT

Change every lowercase letter in msg to uppercase, in place, using arithmetic on chars (no toupper). Leave other characters alone. Then print it: STOP COPYING, START TYPING!

#include <stdio.h>

int main(void) {
    char msg[] = "stop copying, start typing!";

    printf("%s\n", msg);
    return 0;
}
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

Code editor. Press Control or Command plus Enter to run the code. Tab indents; to move focus out of the editor, press Escape and then Tab.