A C string is a writable or read-only sequence of characters whose usable text ends at the first null terminator. This lesson connects array storage, buffer capacity, input handling, and the library functions that inspect or copy character sequences.
In C, a string is an array of characters terminated by a null character '\0'. There is no built-in string type - strings are always char arrays.
// String declaration and initialization
char name[10] = "Alice"; // stored as: A l i c e \0 _ _ _ _
char name[] = "Alice"; // size inferred: 6 bytes (5 chars + \0)
char name[] = {'A','l','i','c','e','\0'}; // explicit null terminator
// String literal (read-only pointer)
char *msg = "Hello"; // pointer to string literal
The <string.h> header provides many useful string manipulation functions:
| Function | Description | Example |
|---|---|---|
| strlen(s) | Returns length of string (excluding \0) | strlen("hello") -> 5 |
| strcpy(dest, src) | Copies src into dest | strcpy(a, "hi") |
| strncpy(dest, src, n) | Copies at most n characters | Safer version of strcpy |
| strcat(dest, src) | Appends src to end of dest | strcat(a, " world") |
| strncat(dest, src, n) | Appends at most n characters | Safer version of strcat |
| strcmp(s1, s2) | Compares two strings; 0 if equal | strcmp("abc","abc") -> 0 |
| strncmp(s1, s2, n) | Compares first n characters | Safer version of strcmp |
| strchr(s, c) | Finds first occurrence of char c | strchr("hello",'l') |
| strstr(s, sub) | Finds first occurrence of substring | strstr("hello","ell") |
| strtok(s, delim) | Splits string by delimiter | strtok(s, ",") |
| sprintf(buf, fmt, ...) | Writes formatted string to buffer | sprintf(buf, "%d", 42) |
| sscanf(s, fmt, ...) | Reads formatted data from string | sscanf("42", "%d", &n) |
#include <stdio.h>
#include <string.h>
int main() {
char name[] = "Alice";
// Print string
printf("Name: %s\n", name);
printf("Length: %zu\n", strlen(name)); // 5
// Access individual characters
printf("Characters: ");
for (int i = 0; name[i] != '\0'; i++) {
printf("%c ", name[i]);
}
printf("\n");
// Null terminator
printf("name[5] = %d (null char)\n", name[5]); // 0
// Reading string with fgets (safer than scanf or gets)
char input[100];
printf("Enter your name: ");
fgets(input, sizeof(input), stdin);
// Remove trailing newline that fgets includes
input[strcspn(input, "\n")] = '\0';
printf("Hello, %s!\n", input);
return 0;
}
#include <stdio.h>
#include <string.h>
int main() {
char s1[50] = "Hello";
char s2[] = "World";
char s3[50];
// strlen
printf("strlen(\"%s\") = %zu\n", s1, strlen(s1)); // 5
// strcpy
strcpy(s3, s1);
printf("strcpy: s3 = \"%s\"\n", s3); // Hello
// strcat
strcat(s1, " ");
strcat(s1, s2);
printf("strcat: s1 = \"%s\"\n", s1); // Hello World
// strcmp
int cmp = strcmp("apple", "banana");
printf("strcmp(\"apple\",\"banana\") = %d\n", cmp); // negative (a < b)
printf("strcmp(\"abc\",\"abc\") = %d\n", strcmp("abc","abc")); // 0
// strchr - find first occurrence of character
char *pos = strchr("Hello World", 'W');
if (pos) printf("strchr found 'W' at: \"%s\"\n", pos); // World
// strstr - find substring
char *sub = strstr("Hello World", "World");
if (sub) printf("strstr found: \"%s\"\n", sub); // World
return 0;
}
#include <stdio.h>
#include <string.h>
void reverseString(char str[]) {
int len = strlen(str);
for (int i = 0; i < len / 2; i++) {
char temp = str[i];
str[i] = str[len - 1 - i];
str[len - 1 - i] = temp;
}
}
int isPalindrome(char str[]) {
int len = strlen(str);
for (int i = 0; i < len / 2; i++) {
if (str[i] != str[len - 1 - i]) return 0;
}
return 1;
}
int main() {
char s1[] = "Hello";
reverseString(s1);
printf("Reversed: %s\n", s1); // olleH
char words[][20] = {"racecar", "hello", "madam", "world"};
for (int i = 0; i < 4; i++) {
printf("\"%s\" is %s\n", words[i],
isPalindrome(words[i]) ? "a palindrome" : "not a palindrome");
}
return 0;
}
/*
Reversed: olleH
"racecar" is a palindrome
"hello" is not a palindrome
"madam" is a palindrome
"world" is not a palindrome
*/
strlen scans memory until it finds \0. If an array is filled without room for the terminator, the function reads beyond the valid characters and causes undefined behavior. Track buffer capacity separately from text length, reserve one byte for \0, and verify that input and copy operations terminate the destination.
scanf does not infer the array capacity from the pointer it receives. Without a field width, it keeps reading a word beyond the destination size. Specify a width smaller than the buffer capacity, or use fgets when spaces and explicit length limits matter.
In an expression, character arrays usually decay to pointers. == compares the addresses, not the character sequences. strcmp compares characters lexicographically and returns zero when the strings are equal.
Explore 500+ free tutorials across 20+ languages and frameworks.