A C-style string stores characters in an array and uses a special final character to say where the text ends. That null character is written \0. It is part of storage but not part of the visible text. Knowing both the text length and the array capacity is necessary to avoid buffer errors.[1]
Review CS1: characters and strings for character literals and text input. This lecture focuses on the manual storage rules that a standard string object manages for you later.
Draw the characters, including the terminator #
The declaration char word[6] = "apple"; has room for six characters. Indexes zero through four hold a, p, p, l, e. Index five holds the terminating zero character. The visible text has length five, while the array has capacity six.
That final slot is not optional for operations expecting a C string. An array of five characters could hold the letters, but would have no slot left for the terminator. The terminator is a character value, distinct from a null pointer: one marks the end of character data, while the other points to no object.
The function strlen counts characters before the first terminator. It does not include the terminator or return the whole capacity. It must be given a valid string with a reachable terminator inside readable storage. If that condition is missing, the function has no supplied length telling it where to stop, so it may read beyond the array.
Initialization is not later array assignment #
A built-in character array can be initialized from a string literal when declared. Afterward, the complete array cannot be replaced with ordinary assignment as though it were a std::string. You can change individual characters or use an appropriate character-copying operation with sufficient storage.
Passing such an array to a function commonly gives the function a pointer to its first character. That pointer alone does not tell the function the array's capacity. A safe interface must provide whatever bound or guarantee the operation needs.
There are therefore two questions before a modification: how many characters should be copied or added, and how much room exists including the final terminator? Answering only the first can still produce an invalid write.
Change one character without changing the boundary #
char text[6] = "apple";
text[0] = 'A'; // "Apple"The declaration gives text six slots and the same terminated five-letter text. The assignment changes index zero from lowercase a to uppercase A. Indexes one through four retain their values, and index five remains the terminator. The result is still a valid C string with the same visible length.
If instead a write replaced index five with another visible letter, the original terminator would disappear. The fact that the write stayed inside the six-element array would not, by itself, mean the result was still a C string. An operation expecting termination would need another zero at a valid position before safely reading it as text.
Copying and appending need different space checks #
strcpy copies the source characters through its terminator. The destination must have room for every visible source character plus that zero, and the source and destination must meet the operation's other requirements, including non-overlap.
strcat appends after the destination's existing visible text. It requires a destination that is already terminated and room for the old text, the added text, and a final terminator. For example, three existing letters followed by two new letters require at least six total slots. Appending is not simply checking that the incoming text alone fits.
A bounded function is not automatically a complete safety solution. strncpy copies up to its specified count and pads when the source is shorter, but does not necessarily add a terminator when the source reaches or exceeds that count. A resulting buffer may need separate termination handling. Read the exact operation's contract, rather than assuming every function with a count produces a valid string.
Compare spelling rather than stored addresses #
Two pointers to separate character arrays can hold different addresses even when both arrays contain the same spelling. Comparing the pointers does not compare the characters.
strcmp compares C-string contents lexicographically. It examines the first differing character to determine ordering. A negative result means the first string precedes the second, zero means their contents compare equal, and a positive result means the first follows the second. Do not require exactly minus one or plus one: only the sign is promised for a nonzero result.
The ordering follows character-representation values. It is not automatically a locale-aware dictionary order for every language or alphabet. For character-level text operations, distinguish the string's contents from both its address and a human-language sorting convention.
Input still needs a boundary plan #
Formatted extraction reads a token separated by whitespace. Line input reads until a line delimiter and can retain spaces in the text. Any character-buffer input operation must respect the actual capacity and its own termination rules.
If numeric extraction leaves a newline pending, a subsequent line read may consume it immediately and produce an empty line. Decide whether that newline should be removed and whether leading spaces or blank lines are meaningful. The C++ string class reduces manual buffer management, but the input delimiter issue remains.
Practice and explanation #
How many slots are required for a terminated five-letter word? Six: one for each visible character and one for the terminating zero. Why can a character array of capacity ten contain text of length three? A terminator can mark the logical end well before the allocated boundary.
If strcmp returns a positive number other than one, has it failed? No. Positive indicates ordering; the exact magnitude is not the comparison's promised result.