Understand the terminating null character
A C string is a sequence of characters ending with a null character, written '\0'. The array must have enough capacity for both the visible characters and that terminator. Character arrays without a terminator are not safe inputs to ordinary string functions.
Length is not capacity
#include
#include
int main(void) {
char name[20] = "Asha";
printf("length=%zu capacity=%zu\n", strlen(name), sizeof name);
if (strcmp(name, "Asha") == 0) {
puts("Names match");
}
return 0;
} Expected output is length=4 capacity=20, followed by Names match. strlen counts the characters before the terminator, not the storage reserved. strcmp compares string contents; comparing two pointers with == does not compare the text stored at their destinations.
Copy and concatenate with bounds in mind
strcpy copies the source and its terminator but does not know the destination capacity. strcat needs room for the destination's existing text, the appended text and one terminator. Verify sizes before using either. snprintf offers a bounded way to format into an array, but its return value must still be checked for errors and truncation.
char label[16];
int written = snprintf(label, sizeof label, "User: %s", "Asha");
if (written < 0 || (size_t)written >= sizeof label) {
puts("Label could not be stored completely");
}Do not assume strncpy is an automatically safe strcpy: if the source is at least as long as the given count, the destination may not be terminated. Use a method whose truncation behavior you understand.
Read a line
char line[80];
if (fgets(line, sizeof line, stdin) != NULL) {
line[strcspn(line, "\n")] = '\0';
printf("You wrote: %s\n", line);
}fgets reads at most capacity minus one characters and terminates a successfully read string. It may retain the newline. If the input line is longer than the buffer, additional text remains to be handled by the next read; a production input loop must detect and manage that case.
String literals and mutation
char word[] = "cat"; creates a modifiable array. A pointer to a string literal must not be used to modify that literal; prefer const char *word = "cat"; for read-only access. An empty string still requires one byte for its terminator.
Exercises
- What capacity is needed for "Hello"? At least six characters including the terminator.
- Compare two names with strcmp and report equal, before or after. Only the sign of a nonzero result matters, not a particular value such as -1.
- Find the length of an empty string. Answer: zero.
- Use snprintf with a deliberately small destination and detect truncation without writing beyond its bounds.