Strings and Character Handling
This domain measures how well you handle NUL-terminated byte strings: the difference between array size and string length, which library functions guarantee termination, and the pitfalls of the character-classification functions.
Representation
- A string is a
chararray ending with a NUL character.strlencounts characters before the NUL;sizeofreports the array's full size, including the terminator. - A string literal has static storage duration and type
char[N], and modifying it is undefined. Adjacent literals are concatenated during translation. - Escape sequences:
\n,\t,\\,\',\",\0, octal such as\101, hex such as\x41. A hex escape consumes as many hex digits as follow, so"\x41B"is one out-of-range character, not the two charactersAB.
<string.h> essentials
- Copying:
strcpyis unbounded;strncpy(dst, src, n)copies up tonbytes and does not terminatedstwhensrcis at leastnbytes long. - Comparing:
strcmp/strncmpreturn a negative value, zero, or a positive value - never rely on exactly1or-1.memcmpcompares raw bytes and does not stop at a NUL. - Overlap:
memmovehandles overlapping regions;memcpyon overlapping regions is undefined. - Searching and splitting:
strchr,strrchr,strstr,strspn,strcspn, andstrtok, which writes into its input and is not reentrant.
Worked example
char s[] = "hello";
char *p = "hello";
printf("%zu %zu %zu\n", sizeof s, strlen(s), sizeof p);
s is a six-element array (h e l l o plus terminator), so sizeof s is 6. strlen(s) is 5. p is a pointer, so sizeof p is the pointer size (commonly 8), not 6. The two objects are distinct: s is writable, while p points at a literal that must not be modified.
Traps
- Passing a buffer with no terminator to any
str*function causes an out-of-bounds read. - Treating
strncpyas a safestrcpywithout manually writingdst[n-1] = '\0'. toupper,isalpha, and friends require anunsigned charvalue orEOF; a negativecharis undefined.- Confusing
sizeofon an array withstrlen, especially after the array decays to a pointer. - Assuming
snprintf's return value is what was written - it is the length that would have been written.