C Notes
Complete reference guide to the C string.h library covering all string and memory functions including strchr, strstr, strtok, memcpy, memset, and more.
The <string.h> header in C provides a comprehensive set of functions for manipulating strings and memory blocks. Beyond the basic strlen, strcpy, strcat, and strcmp, there are powerful searching, tokenizing, and memory manipulation functions that every C programmer should know.
String Searching Functions
strchr() - Find First Occurrence of Character
char *strchr(const char *str, int c);Returns a pointer to the first occurrence of character c in str, or NULL if not found.
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
char *result = strchr(str, 'W');
if (result != NULL) {
printf("Found 'W' at position: %ld\n", result - str);
printf("Substring from 'W': %s\n", result);
}
// Find last occurrence
char *last = strrchr(str, 'l');
if (last != NULL) {
printf("Last 'l' at position: %ld\n", last - str);
}
return 0;
}Found 'W' at position: 7 Substring from 'W': World! Last 'l' at position: 10
strrchr() - Find Last Occurrence of Character
char *strrchr(const char *str, int c);Useful for finding file extensions:
#include <stdio.h>
#include <string.h>
int main() {
char path[] = "/home/user/document.backup.tar.gz";
char *ext = strrchr(path, '.');
if (ext != NULL) {
printf("File extension: %s\n", ext);
}
return 0;
}File extension: .gz
strstr() - Find Substring
char *strstr(const char *haystack, const char *needle);Returns a pointer to the first occurrence of needle in haystack.
#include <stdio.h>
#include <string.h>
int main() {
char text[] = "The quick brown fox jumps over the lazy dog";
char *found = strstr(text, "brown");
if (found != NULL) {
printf("Found \"brown\" at position: %ld\n", found - text);
printf("From match: %s\n", found);
}
// Check if substring exists
if (strstr(text, "cat") == NULL) {
printf("\"cat\" not found in text\n");
}
return 0;
}Found "brown" at position: 10 From match: brown fox jumps over the lazy dog "cat" not found in text
strpbrk() - Find First of Any Characters
char *strpbrk(const char *str, const char *accept);Finds the first character in str that matches ANY character in accept:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "hello123world";
// Find first digit
char *result = strpbrk(str, "0123456789");
if (result != NULL) {
printf("First digit found: '%c' at position %ld\n", *result, result - str);
}
return 0;
}First digit found: '1' at position 5
strspn() and strcspn() - Span Functions
size_t strspn(const char *str, const char *accept); // Length of initial matching segment
size_t strcspn(const char *str, const char *reject); // Length of initial non-matching segment#include <stdio.h>
#include <string.h>
int main() {
char str[] = "123abc456";
// How many initial chars are digits?
size_t digits = strspn(str, "0123456789");
printf("Initial digit span: %lu\n", digits); // 3
// How many initial chars are NOT vowels?
char str2[] = "hello";
size_t nonvowel = strcspn(str2, "aeiou");
printf("Chars before first vowel: %lu\n", nonvowel); // 1 ('h')
return 0;
}Initial digit span: 3 Chars before first vowel: 1
strtok() - String Tokenizer
Splits a string into tokens based on delimiter characters. Note: strtok modifies the original string!
char *strtok(char *str, const char *delimiters);#include <stdio.h>
#include <string.h>
int main() {
char sentence[] = "Hello,World,How,Are,You";
printf("Tokens:\n");
char *token = strtok(sentence, ",");
while (token != NULL) {
printf(" \"%s\"\n", token);
token = strtok(NULL, ","); // Pass NULL for subsequent calls
}
// WARNING: Original string is modified!
printf("\nOriginal after strtok: \"%s\"\n", sentence);
return 0;
}Tokens: "Hello" "World" "How" "Are" "You" Original after strtok: "Hello"
How strtok Works Internally
| Input | "Hello,World,How" |
| Call 1 | strtok(str, ",") |
| Call 2 | strtok(NULL, ",") |
| Call 3 | strtok(NULL, ",") |
| Call 4 | strtok(NULL, ",") |
Parsing CSV-Like Data
#include <stdio.h>
#include <string.h>
int main() {
char data[] = "John:25:Engineer:New York";
char *name = strtok(data, ":");
char *age = strtok(NULL, ":");
char *job = strtok(NULL, ":");
char *city = strtok(NULL, ":");
printf("Name: %s\n", name);
printf("Age: %s\n", age);
printf("Job: %s\n", job);
printf("City: %s\n", city);
return 0;
}Name: John Age: 25 Job: Engineer City: New York
Memory Functions (Also in string.h)
These work on raw memory blocks — not limited to strings.
memcpy() - Copy Memory Block
void *memcpy(void *dest, const void *src, size_t n);Copied: 1 2 3 4 5
memmove() - Safe Copy for Overlapping Memory
Unlike memcpy, memmove handles overlapping source and destination:
Result: World!
memset() - Fill Memory with a Byte Value
void *memset(void *ptr, int value, size_t n);Filled: ********** Zeroed: 0 0 0 0 0
memcmp() - Compare Memory Blocks
#include <stdio.h>
#include <string.h>
int main() {
int a[] = {1, 2, 3, 4, 5};
int b[] = {1, 2, 3, 4, 5};
int c[] = {1, 2, 3, 4, 6};
printf("a vs b: %d\n", memcmp(a, b, sizeof(a))); // 0 (equal)
printf("a vs c: %d\n", memcmp(a, c, sizeof(a))); // negative
return 0;
}a vs b: 0 a vs c: -1
Complete Function Reference Table
| Function | Purpose | Returns |
|---|---|---|
strlen(s) | String length | size_t |
strcpy(d, s) | Copy string | char* to dest |
strncpy(d, s, n) | Copy up to n chars | char* to dest |
strcat(d, s) | Concatenate | char* to dest |
strncat(d, s, n) | Concat up to n | char* to dest |
strcmp(s1, s2) | Compare | int |
strncmp(s1, s2, n) | Compare first n | int |
strchr(s, c) | Find char (first) | char* or NULL |
strrchr(s, c) | Find char (last) | char* or NULL |
strstr(s1, s2) | Find substring | char* or NULL |
strpbrk(s, accept) | Find any of chars | char* or NULL |
strspn(s, accept) | Initial match span | size_t |
strcspn(s, reject) | Initial reject span | size_t |
strtok(s, delim) | Tokenize | char* or NULL |
memcpy(d, s, n) | Copy bytes | void* |
memmove(d, s, n) | Copy (overlap safe) | void* |
memset(s, c, n) | Fill bytes | void* |
memcmp(s1, s2, n) | Compare bytes | int |
memchr(s, c, n) | Find byte | void* or NULL |
Interview Questions
Q1: What's the difference between memcpy and memmove?
memcpy is faster but has undefined behavior when source and destination overlap. memmove handles overlapping regions correctly by using a temporary buffer or copying in the appropriate direction. Use memmove when overlap is possible.
Q2: Why does strtok use NULL for subsequent calls?
strtok maintains a static internal pointer that remembers where it left off. Passing NULL tells it to continue from the last position. This also makes strtok non-reentrant (not thread-safe). Use strtok_r for thread-safe tokenization.
Q3: Can memset be used to initialize an int array to a value like 5?
No, memset sets each byte to the value. For integers, memset(arr, 5, sizeof(arr)) sets each byte to 5, resulting in 0x05050505 per integer (84215045 in decimal). Only 0 and -1 produce expected results for int arrays.
Q4: How would you implement strstr (substring search)?
The naive approach checks each position in the haystack: for each position, compare character-by-character with the needle. Time complexity: O(n×m). More efficient algorithms include KMP (O(n+m)) and Boyer-Moore.
Summary
strchr/strrchrfind single characters;strstrfinds substringsstrtoksplits strings but modifies the original — not thread-safememcpyis fast but unsafe with overlapping memory; usememmovewhen unsurememsetfills bytes, not multi-byte values — only use for 0 or character fillsstrspn/strcspnmeasure span lengths based on character sets- All search functions return NULL on failure — always check before using the result
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for C String Handling Library - Complete string.h Reference.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, strings, string, handling, library, c string handling library - complete string.h reference
Related C Programming Topics