Модуль string.h
Работа со строками и блоками памяти
Модуль string.h предоставляет стандартные функции языка C для работы со строками и блоками памяти. Эти функции позволяют копировать, объединять, сравнивать и искать подстроки в строках, а также манипулировать памятью. Все функции работают с нуль-терминированными строками (завершающимися символом \0), если не указано иное.
Байты, память и строки
Функции работают с байтами. strlen UTF-8 строки возвращает число байт, а не букв; побайтовый поиск и обрезка могут разделить многобайтный символ. Для всех строковых функций нужна доступная завершающая \0, кроме явно ограниченных операций, чьи правила описаны ниже. NULL вместо строки недопустим.
Размер буфера назначения должен быть достаточен вместе с завершающим нулём. memcpy не допускает перекрытия областей; при перекрытии используйте memmove. У strncat параметр n ограничивает число добавляемых байт, а не полный размер dest. strncpy при усечении не добавляет ноль. strcmp/strncmp/memcmp гарантируют знак результата, а не ровно -1 или 1.
strtok изменяет входную строку и хранит состояние между вызовами: вложенный разбор другой строки сбивает текущую последовательность. Строковый литерал для изменения не подходит — используйте массив char.
Для работы с модулем string.h реализованы следующие функции:
// Копирование строк
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
// Объединение строк
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
// Сравнение строк
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
// Поиск символов и подстрок
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
char *strstr(const char *haystack, const char *needle);
char *strpbrk(const char *s, const char *accept);
size_t strspn(const char *s, const char *accept);
size_t strcspn(const char *s, const char *reject);
char *strtok(char *str, const char *delim);
// Длина строки
size_t strlen(const char *s);
// Работа с памятью
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
void *memchr(const void *s, int c, size_t n);
strcpy
Функция char *strcpy(char *dest, const char *src) копирует строку src в буфер dest, включая завершающий нуль-символ.
Параметры:
dest— указатель на буфер назначения (должен быть достаточно большим для хранения строки).src— указатель на копируемую строку.
Возвращаемые значения:
- Указатель на
dest.
Примечание: Не проверяет размер буфера, что может привести к переполнению. Предпочитайте ограниченный буфер и проверку длины; strncpy сама по себе не гарантирует завершающий ноль.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
char dest[20];
const char *src = "Hello, world!";
strcpy(dest, src);
printf("Скопированная строка: %s\n", dest); // Ожидается: Hello, world!
return 0;
}
strncpy
Функция char *strncpy(char *dest, const char *src, size_t n) копирует не более n символов из строки src в буфер dest. Если src короче n, остаток заполняется нуль-символами.
Параметры:
dest— указатель на буфер назначения.src— указатель на копируемую строку.n— максимальное количество копируемых символов.
Возвращаемые значения:
- Указатель на
dest.
Примечание: Если длина src не меньше n, завершающий нуль-символ не добавляется.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
char dest[10];
const char *src = "Hello, world!";
strncpy(dest, src, 5);
dest[5] = '\0'; // Добавляем нуль-символ вручную
printf("Скопированная строка: %s\n", dest); // Ожидается: Hello
return 0;
}
strcat
Функция char *strcat(char *dest, const char *src) добавляет строку src в конец строки dest, включая завершающий нуль-символ.
Параметры:
dest— указатель на строку назначения (должен быть достаточно большим).src— указатель на добавляемую строку.
Возвращаемые значения:
- Указатель на
dest.
Примечание: Не проверяет размер буфера, что может привести к переполнению. Рекомендуется использовать strncat.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
char dest[20] = "Hello";
const char *src = ", world!";
strcat(dest, src);
printf("Объединенная строка: %s\n", dest); // Ожидается: Hello, world!
return 0;
}
strncat
Функция char *strncat(char *dest, const char *src, size_t n) добавляет не более n символов из строки src в конец строки dest и добавляет завершающий нуль-символ.
Параметры:
dest— указатель на строку назначения.src— указатель на добавляемую строку.n— максимальное количество добавляемых символов.
Возвращаемые значения:
- Указатель на
dest.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
char dest[20] = "Hello";
const char *src = ", world!";
strncat(dest, src, 7);
printf("Объединенная строка: %s\n", dest); // Ожидается: Hello, world
return 0;
}
strcmp
Функция int strcmp(const char *s1, const char *s2) сравнивает две строки лексикографически.
Параметры:
s1— указатель на первую строку.s2— указатель на вторую строку.
Возвращаемые значения:
0— строки равны.- Положительное значение —
s1большеs2. - Отрицательное значение —
s1меньшеs2.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s1 = "apple";
const char *s2 = "banana";
int res = strcmp(s1, s2);
printf("Результат сравнения: %d\n", res); // Ожидается: отрицательное значение
return 0;
}
strncmp
Функция int strncmp(const char *s1, const char *s2, size_t n) сравнивает не более n символов двух строк лексикографически.
Параметры:
s1— указатель на первую строку.s2— указатель на вторую строку.n— максимальное количество сравниваемых символов.
Возвращаемые значения:
- Аналогично
strcmp.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s1 = "apple";
const char *s2 = "apricot";
int res = strncmp(s1, s2, 3);
printf("Результат сравнения: %d\n", res); // Ожидается: отрицательное значение
return 0;
}
strchr
Функция char *strchr(const char *s, int c) находит первое вхождение символа c в строке s.
Параметры:
s— указатель на строку.c— искомый символ.
Возвращаемые значения:
- Указатель на первое вхождение
cилиNULL, если не найден.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s = "Hello, world!";
char *pos = strchr(s, ',');
if (pos) {
printf("Найден символ на позиции: %s\n", pos); // Ожидается: , world!
} else {
printf("Символ не найден\n");
}
return 0;
}
strrchr
Функция char *strrchr(const char *s, int c) находит последнее вхождение символа c в строке s.
Параметры:
s— указатель на строку.c— искомый символ.
Возвращаемые значения:
- Указатель на последнее вхождение
cилиNULL, если не найден.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s = "Hello, world!";
char *pos = strrchr(s, 'o');
if (pos) {
printf("Найден символ на позиции: %s\n", pos); // Ожидается: orld!
} else {
printf("Символ не найден\n");
}
return 0;
}
strstr
Функция char *strstr(const char *haystack, const char *needle) находит первое вхождение подстроки needle в строке haystack.
Параметры:
haystack— указатель на строку для поиска.needle— указатель на искомую подстроку.
Возвращаемые значения:
- Указатель на начало подстроки или
NULL, если не найдена.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *haystack = "Hello, world!";
const char *needle = "world";
char *pos = strstr(haystack, needle);
if (pos) {
printf("Найдена подстрока: %s\n", pos); // Ожидается: world!
} else {
printf("Подстрока не найдена\n");
}
return 0;
}
strpbrk
Функция char *strpbrk(const char *s, const char *accept) находит первое вхождение любого символа из строки accept в строке s.
Параметры:
s— указатель на строку для поиска.accept— указатель на строку с допустимыми символами.
Возвращаемые значения:
- Указатель на первое вхождение или
NULL, если не найден.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s = "Hello, world!";
const char *accept = ",!";
char *pos = strpbrk(s, accept);
if (pos) {
printf("Найден символ: %s\n", pos); // Ожидается: , world!
} else {
printf("Символ не найден\n");
}
return 0;
}
strspn
Функция size_t strspn(const char *s, const char *accept) возвращает длину начального сегмента строки s, состоящего только из символов из accept.
Параметры:
s— указатель на строку.accept— указатель на строку с допустимыми символами.
Возвращаемые значения:
- Длина начального сегмента.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s = "123abc";
const char *accept = "0123456789";
size_t len = strspn(s, accept);
printf("Длина сегмента: %zu\n", len); // Ожидается: 3
return 0;
}
strcspn
Функция size_t strcspn(const char *s, const char *reject) возвращает длину начального сегмента строки s, не содержащего символов из reject.
Параметры:
s— указатель на строку.reject— указатель на строку с запрещенными символами.
Возвращаемые значения:
- Длина начального сегмента.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s = "Hello, world!";
const char *reject = ",!";
size_t len = strcspn(s, reject);
printf("Длина сегмента: %zu\n", len); // Ожидается: 5
return 0;
}
strtok
Функция char *strtok(char *str, const char *delim) разбивает строку str на токены, разделенные символами из delim.
Параметры:
str— указатель на строку (при первом вызове) илиNULL(при последующих).delim— указатель на строку с разделителями.
Возвращаемые значения:
- Указатель на следующий токен или
NULL, если токены закончились.
Примечание: Функция модифицирует исходную строку, заменяя разделители на \0. Не является потокобезопасной; рекомендуется использовать strtok_r.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "apple,banana,cherry";
const char *delim = ",";
char *token = strtok(str, delim);
while (token != NULL) {
printf("Токен: %s\n", token);
token = strtok(NULL, delim);
}
// Ожидается: apple\nbanana\ncherry
return 0;
}
strlen
Функция size_t strlen(const char *s) возвращает длину строки s без учета завершающего нуль-символа.
Параметры:
s— указатель на строку.
Возвращаемые значения:
- Длина строки.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s = "Hello";
size_t len = strlen(s);
printf("Длина строки: %zu\n", len); // Ожидается: 5
return 0;
}
memcpy
Функция void *memcpy(void *dest, const void *src, size_t n) копирует n байт из памяти src в dest.
Параметры:
dest— указатель на буфер назначения.src— указатель на источник.n— количество копируемых байт.
Возвращаемые значения:
- Указатель на
dest.
Примечание: Не обрабатывает пересекающиеся области памяти. Для пересекающихся используйте memmove.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
char src[] = "Hello";
char dest[6];
memcpy(dest, src, 6); // Копируем 5 символов + \0
printf("Скопированная строка: %s\n", dest); // Ожидается: Hello
return 0;
}
memmove
Функция void *memmove(void *dest, const void *src, size_t n) копирует n байт из памяти src в dest, корректно обрабатывая пересекающиеся области.
Параметры:
dest— указатель на буфер назначения.src— указатель на источник.n— количество копируемых байт.
Возвращаемые значения:
- Указатель на
dest.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "Hello, world!";
memmove(str + 7, str, 5); // Перемещаем "Hello" на позицию после ", "
printf("Измененная строка: %s\n", str); // Ожидается: Hello, Hello
return 0;
}
memset
Функция void *memset(void *s, int c, size_t n) заполняет n байт памяти s значением c (как байт).
Параметры:
s— указатель на память.c— значение для заполнения.n— количество байт.
Возвращаемые значения:
- Указатель на
s.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
char buf[10];
memset(buf, 'A', 10);
buf[9] = '\0'; // Добавляем нуль-символ
printf("Заполненный буфер: %s\n", buf); // Ожидается: AAAAAAAAA
return 0;
}
memcmp
Функция int memcmp(const void *s1, const void *s2, size_t n) сравнивает n байт памяти s1 и s2.
Параметры:
s1— указатель на первую область памяти.s2— указатель на вторую область памяти.n— количество сравниваемых байт.
Возвращаемые значения:
0— области равны.- Положительное значение —
s1большеs2. - Отрицательное значение —
s1меньшеs2.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s1 = "apple";
const char *s2 = "apricot";
int res = memcmp(s1, s2, 3);
printf("Результат сравнения: %d\n", res); // Ожидается: отрицательное значение
return 0;
}
memchr
Функция void *memchr(const void *s, int c, size_t n) находит первое вхождение байта c в первых n байтах памяти s.
Параметры:
s— указатель на память.c— искомый байт.n— количество байт для поиска.
Возвращаемые значения:
- Указатель на вхождение или
NULL, если не найден.
Пример использования:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s = "Hello, world!";
void *pos = memchr(s, ',', 10);
if (pos) {
printf("Найден символ: %c\n", *(char *)pos); // Ожидается: ,
} else {
printf("Символ не найден\n");
}
return 0;
}