Introduction
C has no separate string type. A string is an array of char that ends with a special character, '\0' (the number 0), which marks where the text stops.
Other languages hide how text is stored, but C shows you. A string is simply an array of characters with a marker at the end, and understanding that explains both C's speed and many of the most serious security bugs in history.
How it works
string.h
| Function | Does |
|---|---|
strlen(s) | number of characters, not counting '\0' |
strcpy(dest, src) | copy src into dest |
strcat(dest, src) | add src to the end of dest |
strcmp(a, b) | 0 if equal, negative if a comes first, positive if b does |
You cannot copy strings with = or compare them with ==. Use strcpy and strcmp.
Too small a buffer
The array must have room for every character plus the '\0'. Real C writes past the end without warning (a "buffer overflow", the cause of many security holes). StepVioz stops and says how much room there was:
#include <stdio.h>
#include <string.h>
int main(void) {
char city[6];
strcpy(city, "Dhaka");
printf("%s\n", city);
strcpy(city, "Chattogram");
printf("%s\n", city);
return 0;
}Walking through a string
#include <stdio.h>
int main(void) {
char text[] = "Programming";
int vowels = 0;
for (int i = 0; text[i] != '\0'; i++) {
char c = text[i];
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
vowels++;
}
}
printf("%s has %d vowels\n", text, vowels);
return 0;
}A loop can stop at the '\0': for (int i = 0; s[i] != '\0'; i++).
Syntax
char word[20] = "hello";
strlen(word);
strcpy(word, "bye");
strcat(word, "!");
strcmp(a, b) == 0;
fgets(line, sizeof line, stdin);
Example
#include <stdio.h>
#include <string.h>
int main(void) {
char name[10] = "Rafi";
printf("%s has %d letters\n", name, (int)strlen(name));
strcat(name, "q");
name[0] = 'r';
printf("%s\n", name);
printf("%d\n", strcmp(name, "rafiq") == 0);
return 0;
}In the memory panel, name shows its characters cell by cell, with the '\0' after the last letter, and the text it spells above the cells. char name[10] = "Rafi" uses 5 of the 10 bytes: four letters plus '\0'.
Line by line
namehas room for 10 characters, and starts with"Rafi"and its'\0'.strlencounts up to the'\0', so it gives 4.strcatadds"q"at the end, and moves the'\0'along.name[0] = 'r'changes one character in place.strcmpgives 0 when the two texts match, so the comparison prints 1.
Expected result
Rafi has 4 letters
rafiq
1
In the real world
Almost every serious computer attack of the 1990s and 2000s used a buffer overflow in string handling. Modern C code uses size-limited functions, and languages such as Rust were designed to rule this mistake out.
Common mistakes
char s[5] = "Hello";has no room for'\0'(it needs 6).- Comparing with
==:if (a == b)compares addresses, not text. Usestrcmp(a, b) == 0. scanf("%s", name)stops at the first space. To read a whole line, usefgets(name, sizeof name, stdin).- Never use
gets: it was removed from C because it cannot stop at the end of the array.
Best practices
- Always count the
'\0'when you size an array. - Use
fgets, which takes a size, for lines of input. - Use
sizeof arrayfor the size, instead of typing the number again.
Summary
A C string is a char array ending in '\0'. The functions in string.h copy, join, measure and compare strings. The programmer is responsible for leaving enough room.
Quick check
Key takeaways
- A string needs one extra byte for '\0'.
- Compare strings with strcmp, not ==.
- fgets can read a whole line and limits how much it reads.
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.