Reference: string.h
Length, copying, comparing, searching, splitting, and raw memory.
6 minute read
Big idea
<string.h> works on strings (char arrays ending in '\0') and on raw memory. None of these functions know how big your arrays are — making sure there's room is always your job.
Length and copying
strlen
size_t strlen(const char *s);
The number of characters before the '\0'. See String Functions.
- Gotcha: it walks the whole string every call — don't put it in a loop condition over a long string. Print the result with
%zu.sizeofis different: it's the array's size, not the text's length. - Example:
strlen("hello")→ 5
strcpy / strncpy
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
Copy src into dest, including the '\0'.
- Gotcha:
strcpyoverflowsdestif it's too small.strncpystops atnbut then doesn't add'\0'ifsrcwas too long. Safer:snprintf(dest, sizeof dest, "%s", src);. - Example:
char name[20]; strcpy(name, "Asha");
strcat / strncat
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
Append src to the end of dest. strncat appends at most n characters and always adds '\0'.
- Gotcha:
destmust have room for both strings plus'\0', and must already be a valid string (start withchar buf[50] = "";). - Example:
strcat(path, "/notes.txt");
Comparing
strcmp / strncmp
int strcmp(const char *a, const char *b);
int strncmp(const char *a, const char *b, size_t n);
Compare alphabetically (by character code): negative if a comes first, 0 if equal, positive if b comes first. strncmp compares at most n characters.
- Gotcha:
a == bcompares addresses, not text — usestrcmp(a, b) == 0. Uppercase letters sort before lowercase ("Zoo"<"apple"). - Example:
if (strncmp(line, "GET ", 4) == 0) …
Searching
strchr / strrchr
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
Find the first (or last) occurrence of a character; NULL if absent.
- Example:
char *dot = strrchr("photo.tar.gz", '.');→".gz"
strstr
char *strstr(const char *haystack, const char *needle);
Find the first occurrence of a substring; NULL if absent.
- Example:
if (strstr(msg, "error")) …
strcspn / strspn
size_t strcspn(const char *s, const char *reject);
size_t strspn(const char *s, const char *accept);
Length of the starting run of s made of characters not in reject (or only those in accept).
- Example:
line[strcspn(line, "\n")] = '\0';— stripfgets's newline.
strtok
char *strtok(char *s, const char *delims);
Splits a string into tokens. Call with the string first, then with NULL to get the next token.
- Gotcha: it modifies the string (writes
'\0'over delimiters), so it can't be used on a literal, and it remembers its place in a hidden static variable, so you can't split two strings at once. - Example:
for (char *t = strtok(buf, ", "); t; t = strtok(NULL, ", ")) puts(t);
Raw memory
memset
void *memset(void *p, int value, size_t bytes);
Sets every byte to value.
- Gotcha: it works byte by byte:
memset(a, 0, sizeof a)zeroes an int array, butmemset(a, 1, …)makes each int 16843009, not 1. - Example:
memset(grid, 0, sizeof grid);
memcpy / memmove
void *memcpy(void *dest, const void *src, size_t bytes);
void *memmove(void *dest, const void *src, size_t bytes);
Copy bytes bytes. memmove is safe when the two regions overlap; memcpy isn't.
- Example:
memmove(a, a + 1, (n - 1) * sizeof a[0]);— shift an array left by one
memcmp
int memcmp(const void *a, const void *b, size_t bytes);
Compares bytes, like strcmp but it doesn't stop at '\0'.
strerror
char *strerror(int errnum);
The text for an error number — usually strerror(errno). See Error Handling.
#include <stdio.h>
#include <string.h>
int main(void) {
char buf[64] = "";
strcat(buf, "red,green");
strncat(buf, ",blue,yellow", 5);
printf("%s (%zu chars)\n", buf, strlen(buf));
printf("strcmp: %d\n", strcmp("apple", "apple") == 0);
printf("strstr: %s\n", strstr(buf, "green"));
for (char *t = strtok(buf, ","); t != NULL; t = strtok(NULL, ",")) {
printf("[%s] ", t);
}
printf("\n");
int a[5] = {1, 2, 3, 4, 5};
memmove(a, a + 1, 4 * sizeof a[0]);
for (int i = 0; i < 5; i++) printf("%d ", a[i]);
printf("\n");
return 0;
}output
red,green,blue (14 chars)
strcmp: 1
strstr: green,blue
[red] [green] [blue]
2 3 4 5 5 Run and edit it in the app.
How do you test whether the strings a and b hold the same text?
Check yourself
Which function is safe when the source and destination overlap?
What does strtok do to the string you pass it?