Strings
Text in CC has no special string type: a string is a char array whose text ends with the null character '\0'. In the lab below you watch printf hunt for that terminator, see the garbage that appears without it, count a string's length yourself, and compare scanf and fgets when the user types a name with a space.
- char s[6]room for 5 letters + '\0'
- '\0'marks the end of the text
- fgetsreads a whole line safely
Ready
Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode
The ideas behind the lab
Exactly what you watched happen, in plain steps.
A string is a char array with an end mark
C stores text as an array of char. After the last character comes the null character '\0' (the byte 0), which marks where the text ends — every string function walks the array until it meets it. So the array must always have one cell more than the number of characters. A string literal like "Hi" already contains that '\0': it is 3 bytes.
char a[6] = "Hello"; // H e l l o \0
char b[] = "Hi"; // size 3: H i \0
char c[10] = "Hi"; // H i \0 \0 … (rest filled with \0)
char d[5] = {'H','e','l','l','o'}; // NOT a string: no \0!
printf("%s\n", a); // prints until \0
printf("%c\n", a[1]); // e — one character
| Code | What it does | Watch out |
|---|---|---|
| char s[20] = "text"; | Array with the text + '\0' | Size ≥ length + 1 |
| printf("%s", s); | Prints up to '\0' | Pass s, not &s or *s |
| scanf("%19s", s); | Reads one word (stops at a space) | No &; give a width limit |
| fgets(s, sizeof s, stdin); | Reads a whole line, keeps '\n' | Remove the '\n' if not wanted |
| s[i] | One character (a char) | i must be < the length |
| for (i = 0; s[i] != '\0'; i++) | Visits every character | Stops before the terminator |
Strings in memory
- Each character is one char (1 byte) holding its ASCII code.
- '\0' is the char with value 0 — not the digit '0' (48).
- "Hi" is a string literal: H, i and '\0' — 3 bytes.
- An initialised array gets '\0' automatically if there is room.
- Length = characters before '\0'; sizeof = the whole array.
Printing and walking
- %s needs the address of the first char: printf("%s", s).
- printf prints character after character until '\0'.
- Without '\0' it runs past the array and prints garbage (or crashes).
- Loop with s[i] != '\0' — you do not need to know the length.
- Change one character with s[i] = 'X'; the array must not be a literal pointer.
Reading text safely
- scanf("%s", s) — no & because s is already an address.
- %s stops at the first space, tab or newline: it reads one word.
- Always limit it: %19s for char s[20], or the input can overflow the array.
- fgets(s, sizeof s, stdin) reads a line with spaces, and never overflows.
- fgets keeps the '\n': remove it with s[strcspn(s, "\n")] = '\0'. Never use gets().
Read a full name and count its vowels
Every line, explained.
#include <stdio.h>
#include <string.h>
For strcspn.
int main(void)
{
char line[50];
Room for 49 characters + '\0'.
printf("Your name: ");
fgets(line, sizeof line, stdin);
The user types Ada Lovelace — the space is kept.
line[strcspn(line, "\n")] = '\0';
Replace the '\n' fgets kept with '\0'.
int vowels = 0;
for (int i = 0; line[i] != '\0'; i++) {
Walk until the terminator.
char c = line[i];
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
vowels++;
a, o, e, a, e
}
printf("Hello, %s! (%d vowels)\n", line, vowels);
Prints Hello, Ada Lovelace! (5 vowels)
return 0;
}
Spot the bug
Mistakes almost every beginner makes — and how to fix them.
No room for '\0'
char s[5] = "Hello"; // 5 letters, no terminator
char s[6] = "Hello"; // or: char s[] = "Hello";
The array is full with the letters, so '\0' is dropped and %s runs past the end.
& with %s in scanf
scanf("%s", &name);
scanf("%19s", name);
An array name already is an address. Also give a width so long input cannot overflow.
Expecting %s to read a full name
scanf("%s", name); // types: Ada Lovelace
// name = "Ada"
fgets(name, sizeof name, stdin);
%s stops at the first space; the rest stays in the input buffer for the next read.
Comparing strings with ==
if (answer == "yes")
if (strcmp(answer, "yes") == 0)
== compares two addresses, never the text. strcmp compares character by character (Module 28).
Assigning a string with =
char s[10]; s = "hi"; // error
char s[10]; strcpy(s, "hi");
Arrays cannot be assigned. Initialise when declaring, or copy with strcpy.
Check your understanding
Answer each question — you will see the explanation straight away.
How many bytes does the string literal "cat" take?
3 letters + '\0'.
Which character ends every C string?
The null character, value 0.
char s[] = "Hello"; s[2] = '\0'; printf("%s", s); prints?
printf stops at the first '\0', now at index 2.
The user types "New York". What does scanf("%s", city) store?
%s stops at the space.
char s[] = "Hi"; — what is sizeof s?
H, i and '\0'.
Strings quiz
Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.