Модуль 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;
}