C-Style Strings
A C-style string is just a char array with a special character stored in the last slot:
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};That last element, '\0', is called the null terminator, and its only job is to mark where the text ends. To read the entire string, code has to scan forward one character at a time until it hits that terminator.
String literals
Writing a string like {'H', 'e', 'l', 'l', 'o', '\0'} by hand every time can be a pain, so C++ lets you use a literal to do the same thing:
char greeting[] = "Hello";The compiler counts the characters, adds the null terminator automatically, and infers the array size (six elements for five visible letters).
A string literal like "Hello" has the type const char[6], an array of 6 const char values. Writing char greeting[] = "Hello"; copies those characters into a new, non-const array you’re allowed to modify. The literal itself stays read-only.
If you ever declare the string size explicitly, make sure you reserve an extra slot for \0:
char greeting[6] = "Hello"; // 5 visible characters + 1 for '\0'If you undersize it, say char greeting[5], the compiler either flags it as an error or silently leaves out the terminator. You end up with an array that looks like a string but has no defined end, so any function processing it will keep reading beyond the array.
Functions in <cstring>
The standard library contains a header, <cstring>, full of functions for working with these character arrays. They all lean on the null terminator to know where to stop.
Measuring length with strlen
strlen counts the characters in a string excluding the null terminator:
It’s worth seeing what strlen is actually doing, because the logic shows up constantly when you work with char arrays yourself:
char drink[] = "coffee";std::size_t count = 0;while (drink[count] != '\0') { count++;}// count is now 6This walks through all characters, stopping at '\0'. This would also work if we replaced "coffee" with the empty string, "", as it’s an array containing exactly one character '\0'.
Copying and concatenating with strcpy and strcat
strcpy copies one C-string into another, and strcat (which is short for “string concatenate”) appends one onto the end of an existing string:
Here, strcpy replaces “Order pending” held by the destination, while strcat adds the new text to the end of what strcpy left behind.
Both functions write a fresh terminator when they finish.
Why strcpy and strcat are risky
strcpy and strcat have no idea about the size of the destination array. They trust you to have allocated enough space. So, the following code is problematic because the string literal has 13 characters (including '\0') while the destination array can hold 8 characters:
char username[8];strcpy(username, "autumn_glow3"); // Destination is only 8 bytes, this string needs 13Once again, this leads to writing beyond the array’s bounds, just triggered indirectly through strcpy. Historically, hackers have built entire careers exploiting buffer overflows like this one.
The fix is to use strncpy, a version of strcpy that takes a maximum number of characters to copy. strcat has a bounded counterpart too, strncat, which works the same way.
Because of the limit passed to strncpy, it never copies more than the specified number of characters. However, it doesn’t guarantee a terminator character: if the source string is at least as long as that limit, every slot gets filled with real characters, and there’s no room left for '\0'. That’s why sizeof(username) - 1 is passed to the function on line 6 rather than the full size, to leave one byte free for the null terminator. You have to add the terminator explicitly, as shown on line 7.
Comparing strings with strcmp
You can’t compare C-style strings with ==. It compares the memory addresses of the two arrays, not the text stored in them. Use strcmp instead:
strcmp returns 0 when the strings match, a negative number if the first string appears before the second when ordered alphabetically, and a positive number otherwise. This three-way result makes sense once you know it’s meant to double as a sorting comparison.
Checkpoint
You declare char code[6] = "Ticket"; in your code. What happens?
Why are strcpy and strcat risky to use directly on a fixed-size buffer?
What does strlen return for char word[] = "cat";?
You compare two char arrays holding the same word using array1 == array2, and the result is false. Why?