C String Library Functions: Complete Guide to string.h

The string.h header file provides a comprehensive collection of functions for string manipulation in C, eliminating the need to implement these operations manually [web:155]. These standardized, optimized functions handle common tasks like copying, comparing, concatenating, and searching strings. However, many traditional string functions come with significant security risks—particularly buffer overflows—that have plagued C programs for decades. Understanding both how to use these functions and their safety implications is crucial for writing secure C code.
This comprehensive guide explores all essential string.h functions including strlen, strcpy, strcmp, strcat, and their safer alternatives, along with search and tokenization functions [web:156][web:159]. You'll learn proper usage, understand buffer overflow risks, and discover best practices for safe string handling that prevent common vulnerabilities while maintaining code efficiency.
Essential String Functions Overview
The string.h library includes several categories of functions: measurement (strlen), copying (strcpy, strncpy), concatenation (strcat, strncat), comparison (strcmp, strncmp), and searching (strchr, strstr, strtok) [web:159]. All these functions require including the string.h header at the beginning of your program.
#include <stdio.h>
#include <string.h> // Required for string functions
int main() {
// Example demonstrating basic usage
char str1[50] = "Hello";
char str2[50] = "World";
char str3[100];
// strlen - get string length
printf("Length of '%s': %zu\n", str1, strlen(str1));
// strcpy - copy string
strcpy(str3, str1);
printf("Copied string: %s\n", str3);
// strcat - concatenate strings
strcat(str3, " ");
strcat(str3, str2);
printf("Concatenated: %s\n", str3);
// strcmp - compare strings
int result = strcmp(str1, str2);
printf("Comparison result: %d\n", result);
return 0;
}strlen: Measuring String Length
The strlen() function returns the number of characters in a string, excluding the null terminator [web:155][web:159]. It traverses the string character by character until it encounters '\0', making its time complexity O(n). This is one of the safest string functions since it only reads memory without modifying it.
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Hello, World!";
char str2[] = "";
char str3[100] = "Programming";
// Syntax: size_t strlen(const char *str)
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
size_t len3 = strlen(str3);
printf("Length of '%s': %zu\n", str1, len1); // 13
printf("Length of empty string: %zu\n", len2); // 0
printf("Length of '%s': %zu\n", str3, len3); // 11
// Common use: loop control
printf("\nCharacters in '%s':\n", str1);
for (size_t i = 0; i < strlen(str1); i++) {
printf("%c ", str1[i]);
}
printf("\n");
// Performance tip: Cache length in loops
size_t len = strlen(str1); // Calculate once
for (size_t i = 0; i < len; i++) {
// Process - more efficient than calling strlen repeatedly
}
// Important: strlen counts characters, not bytes
// For array size, remember to add 1 for null terminator
char buffer[len1 + 1]; // Correct size allocation
strcpy(buffer, str1);
return 0;
}strcpy and strncpy: Copying Strings
The strcpy() function copies a string from source to destination, including the null terminator [web:155][web:156]. However, it performs no bounds checking and will happily overflow the destination buffer if the source is too large. The safer alternative, strncpy(), limits the number of characters copied but has quirks that require careful handling [web:163].
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "Hello, World!";
char dest1[50];
char dest2[10];
char dest3[10];
// strcpy: Unsafe - no bounds checking
// Syntax: char *strcpy(char *dest, const char *src)
strcpy(dest1, source); // OK - dest1 is large enough
printf("strcpy result: %s\n", dest1);
// strcpy(dest2, source); // DANGER! Buffer overflow
// source has 13 chars + null = 14 bytes, dest2 only has 10
// strncpy: Safer - limits characters copied
// Syntax: char *strncpy(char *dest, const char *src, size_t n)
strncpy(dest2, source, sizeof(dest2) - 1);
dest2[sizeof(dest2) - 1] = '\0'; // MUST manually add null terminator!
printf("strncpy result: %s\n", dest2); // "Hello, Wo"
// strncpy quirk: If src < n, pads with null bytes
char short_src[] = "Hi";
strncpy(dest3, short_src, sizeof(dest3));
printf("Padded copy: %s\n", dest3);
// Safe copying pattern
char safe_dest[20];
size_t dest_size = sizeof(safe_dest);
if (strlen(source) < dest_size) {
strcpy(safe_dest, source); // Safe - we checked first
} else {
strncpy(safe_dest, source, dest_size - 1);
safe_dest[dest_size - 1] = '\0';
}
printf("Safe copy: %s\n", safe_dest);
return 0;
}strcmp and strncmp: Comparing Strings
The strcmp() function compares two strings lexicographically, returning 0 if equal, a negative value if the first string is less than the second, or a positive value if greater [web:156][web:159]. The comparison is based on ASCII values and is case-sensitive. The bounded version strncmp() compares only the first n characters.
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Apple";
char str2[] = "Banana";
char str3[] = "Apple";
char str4[] = "apple"; // Different case
// strcmp: Compare entire strings
// Syntax: int strcmp(const char *str1, const char *str2)
int result1 = strcmp(str1, str2);
int result2 = strcmp(str1, str3);
int result3 = strcmp(str1, str4);
printf("strcmp('%s', '%s') = %d\n", str1, str2, result1); // < 0
printf("strcmp('%s', '%s') = %d\n", str1, str3, result2); // 0
printf("strcmp('%s', '%s') = %d\n", str1, str4, result3); // < 0 ('A' < 'a')
// Proper usage in conditionals
if (strcmp(str1, str3) == 0) {
printf("\n'%s' and '%s' are equal\n", str1, str3);
}
if (strcmp(str1, str2) < 0) {
printf("'%s' comes before '%s' alphabetically\n", str1, str2);
}
// strncmp: Compare first n characters
// Syntax: int strncmp(const char *str1, const char *str2, size_t n)
char prefix1[] = "Hello World";
char prefix2[] = "Hello Universe";
int full_cmp = strcmp(prefix1, prefix2);
int partial_cmp = strncmp(prefix1, prefix2, 5); // Compare first 5 chars
printf("\nFull comparison: %d\n", full_cmp); // Not equal
printf("First 5 chars: %d\n", partial_cmp); // Equal (both "Hello")
// Practical use: Check if string starts with prefix
char text[] = "Programming in C";
char check[] = "Program";
if (strncmp(text, check, strlen(check)) == 0) {
printf("\n'%s' starts with '%s'\n", text, check);
}
return 0;
}strcat and strncat: Concatenating Strings
The strcat() function appends the source string to the end of the destination string [web:156]. Like strcpy(), it performs no bounds checking and can cause buffer overflows. The safer strncat() limits how many characters are appended, but it has different behavior than strncpy regarding null termination [web:160].
#include <stdio.h>
#include <string.h>
int main() {
char dest1[50] = "Hello";
char dest2[15] = "Good";
char dest3[20] = "C ";
char src[] = " World";
// strcat: Unsafe concatenation
// Syntax: char *strcat(char *dest, const char *src)
strcat(dest1, src); // OK - enough space
printf("strcat result: %s\n", dest1); // "Hello World"
// strcat(dest2, " Morning and Afternoon"); // DANGER! Overflow
// strncat: Safer - limits characters appended
// Syntax: char *strncat(char *dest, const char *src, size_t n)
strncat(dest2, " Morning", sizeof(dest2) - strlen(dest2) - 1);
printf("strncat result: %s\n", dest2); // "Good Morning"
// strncat DOES add null terminator (unlike strncpy)
strncat(dest3, "Programming", 7); // Appends only 7 chars
printf("Partial append: %s\n", dest3); // "C Program"
// Safe concatenation pattern
char buffer[30] = "Safe";
char append[] = " String Concatenation";
size_t available = sizeof(buffer) - strlen(buffer) - 1;
if (strlen(append) <= available) {
strcat(buffer, append);
} else {
strncat(buffer, append, available);
}
printf("Safe concat: %s\n", buffer);
// Building strings incrementally
char result[100] = "";
strcat(result, "First");
strcat(result, " ");
strcat(result, "Second");
strcat(result, " ");
strcat(result, "Third");
printf("Built string: %s\n", result);
return 0;
}String Search Functions
The string.h library provides several functions for searching within strings: strchr() finds the first occurrence of a character, strrchr() finds the last occurrence, and strstr() searches for a substring [web:159]. These functions return pointers to the found location or NULL if not found.
#include <stdio.h>
#include <string.h>
int main() {
char text[] = "Programming in C is powerful";
// strchr: Find first occurrence of character
// Syntax: char *strchr(const char *str, int ch)
char *found = strchr(text, 'i');
if (found != NULL) {
printf("First 'i' found at position: %ld\n", found - text);
printf("Remaining string: %s\n", found);
}
// strrchr: Find last occurrence of character
// Syntax: char *strrchr(const char *str, int ch)
char *last = strrchr(text, 'i');
if (last != NULL) {
printf("\nLast 'i' found at position: %ld\n", last - text);
}
// strstr: Find substring
// Syntax: char *strstr(const char *haystack, const char *needle)
char *substring = strstr(text, "in C");
if (substring != NULL) {
printf("\nSubstring 'in C' found at position: %ld\n",
substring - text);
printf("From that position: %s\n", substring);
} else {
printf("Substring not found\n");
}
// Practical example: Check file extension
char filename[] = "document.txt";
char *extension = strrchr(filename, '.');
if (extension != NULL) {
printf("\nFile extension: %s\n", extension); // ".txt"
if (strcmp(extension, ".txt") == 0) {
printf("This is a text file\n");
}
}
// Count occurrences of a character
char sentence[] = "Hello, how are you?";
int count = 0;
char *ptr = sentence;
while ((ptr = strchr(ptr, 'o')) != NULL) {
count++;
ptr++; // Move past the found character
}
printf("\nLetter 'o' appears %d times\n", count);
// Replace character using strchr
char message[] = "Hello-World-Example";
char *pos = message;
while ((pos = strchr(pos, '-')) != NULL) {
*pos = ' '; // Replace '-' with space
pos++;
}
printf("After replacement: %s\n", message);
return 0;
}strtok: String Tokenization
The strtok() function splits a string into tokens based on delimiters [web:161][web:164]. It's commonly used for parsing comma-separated values, splitting sentences into words, or processing formatted input. However, strtok() modifies the original string by inserting null terminators, making it destructive and not thread-safe.
#include <stdio.h>
#include <string.h>
int main() {
// strtok modifies the original string, so use a copy
char sentence[] = "Learning C programming is fun";
char copy[100];
strcpy(copy, sentence);
// Syntax: char *strtok(char *str, const char *delim)
// First call: pass the string
char *token = strtok(copy, " ");
printf("Tokens:\n");
while (token != NULL) {
printf(" %s\n", token);
// Subsequent calls: pass NULL
token = strtok(NULL, " ");
}
// CSV parsing example
char csv[] = "Apple,Banana,Cherry,Date";
char csv_copy[50];
strcpy(csv_copy, csv);
printf("\nCSV values:\n");
token = strtok(csv_copy, ",");
int index = 1;
while (token != NULL) {
printf(" Item %d: %s\n", index++, token);
token = strtok(NULL, ",");
}
// Multiple delimiters
char text[] = "one,two;three:four five";
char text_copy[50];
strcpy(text_copy, text);
printf("\nMultiple delimiters (,;: ):\n");
token = strtok(text_copy, ",;: ");
while (token != NULL) {
printf(" %s\n", token);
token = strtok(NULL, ",;: ");
}
// Parsing key-value pairs
char config[] = "name=John,age=25,city=NewYork";
char config_copy[100];
strcpy(config_copy, config);
printf("\nConfiguration:\n");
token = strtok(config_copy, ",");
while (token != NULL) {
char *equals = strchr(token, '=');
if (equals != NULL) {
*equals = '\0'; // Split at '='
char *key = token;
char *value = equals + 1;
printf(" %s: %s\n", key, value);
}
token = strtok(NULL, ",");
}
return 0;
}Function Comparison and Safety
Understanding which functions are safe and which pose risks is crucial for secure programming [web:160]. The bounded versions (strncpy, strncat, strncmp) provide some protection but require careful usage to avoid pitfalls.
| Function | Purpose | Safety | Notes |
|---|---|---|---|
| strlen() | Get string length | Safe | Read-only, no modification |
| strcpy() | Copy string | Unsafe | No bounds checking—use strncpy() |
| strncpy() | Copy n characters | Safer | May not null-terminate—manual add needed |
| strcat() | Concatenate strings | Unsafe | No bounds checking—use strncat() |
| strncat() | Concatenate n chars | Safer | Does guarantee null termination |
| strcmp() | Compare strings | Safe | Read-only, returns int |
| strncmp() | Compare n chars | Safe | Useful for prefix checking |
| strchr() | Find character | Safe | Returns pointer or NULL |
| strstr() | Find substring | Safe | Returns pointer or NULL |
| strtok() | Tokenize string | Destructive | Modifies original, not thread-safe |
Best Practices for Safe String Handling
Following best practices when using string.h functions prevents buffer overflows, crashes, and security vulnerabilities. These guidelines help you write robust, secure string manipulation code.
- Always validate buffer sizes: Check that destination buffers are large enough before copying or concatenating
- Prefer bounded functions: Use strncpy(), strncat(), strncmp() over their unbounded counterparts
- Manually ensure null termination: After strncpy(), always set
dest[n-1] = '\0'to guarantee termination - Calculate available space correctly: For concatenation:
sizeof(dest) - strlen(dest) - 1 - Copy before tokenizing: strtok() modifies the string—work on a copy if you need the original
- Check return values: Functions like strchr(), strstr() return NULL when not found—always check before using
- Use sizeof() wisely: Works for arrays declared in same scope, not for pointers or function parameters
- Consider modern alternatives: C11 provides safer functions like strcpy_s() and strcat_s() when available
Conclusion
The string.h library provides essential functions for string manipulation in C, from basic operations like strlen() and strcmp() to complex tasks like tokenization with strtok(). Understanding both the capabilities and limitations of these functions is crucial—while they eliminate the need for manual implementation, many traditional functions like strcpy() and strcat() pose serious security risks through buffer overflow vulnerabilities. The bounded alternatives (strncpy, strncat) offer better protection but require careful usage, particularly regarding null termination.
Always validate buffer sizes before operations, prefer bounded functions over unbounded ones, and manually ensure null termination when using strncpy(). Check return values from search functions, make copies before using strtok(), and calculate available space correctly for concatenation. By following these best practices and understanding the behavior and safety characteristics of each function, you'll write more secure, robust C code that handles strings safely while avoiding the buffer overflows and undefined behavior that have plagued C programs for decades. Master these functions, and you'll have the tools needed for all string processing tasks in C programming.
$ share --platform
$ cat /comments/ (0)
$ cat /comments/
// No comments found. Be the first!


