8. Глава 8: Библиотека строк (<string.h>)

В этой главе мы погрузимся в стандартную библиотеку языка C и рассмотрим функции из заголовочного файла <string.h>. Эти функции являются основой для работы со строками в стиле C (массивами символов, завершающимися нулевым символом \0).

## Основные функции для работы со строками

Ниже представлены ключевые функции, с которыми вы будете часто сталкиваться при работе со строками.

  1. `strlen`

    Эта функция позволяет узнать длину строки. Важно помнить, что она не включает завершающий нулевой символ \0 в подсчет.

    #include <string.h>
    size_t len = strlen("Hello"); // len будет равно 5
    
  2. `strcpy`

    Используется для копирования содержимого одной строки в другую. Будьте осторожны: убедитесь, что целевой массив достаточно велик для размещения копируемой строки, иначе произойдет переполнение буфера.

    #include <string.h>
    char src[] = "World";
    char dest[10]; // Убедитесь, что dest достаточно большой
    strcpy(dest, src); // dest теперь содержит "World"
    
  3. `strcmp`

    Эта функция сравнивает две строки. Она возвращает 0, если строки идентичны. Если строки отличаются, возвращается ненулевое значение (отрицательное, если первая строка «меньше» второй, и положительное, если «больше» — по лексикографическому порядку). Помните, что strcmp чувствительна к регистру!

    #include <string.h>
    int result = strcmp("abc", "abc"); // result будет равно 0 (строки равны)
    int result2 = strcmp("abc", "abd"); // result2 будет отрицательным
    int result3 = strcmp("Hello", "hello"); // result3 будет ненулевым (разный регистр)
    
  4. `strcat`

    Используется для конкатенации (объединения) двух строк. Она добавляет содержимое второй строки в конец первой. Внимание: убедитесь, что целевой массив (первый аргумент) имеет достаточный размер для хранения объединенных строк, иначе рискуете получить переполнение буфера.

    #include <string.h>
    char str[20] = "Hello, "; // str должен быть достаточно большим
    strcat(str, "world!"); // str теперь содержит "Hello, world!"
    

## Дополнительные, но не менее полезные функции

Помимо основных, существуют и другие функции, которые значительно облегчают работу со строками и повышают безопасность кода:

  • strncpy: Более безопасная версия strcpy. Она позволяет указать максимальное количество символов для копирования, что помогает предотвратить переполнение буфера.

  • strncmp: Позволяет сравнивать только первые N символов двух строк, что полезно, когда вам не нужно полное сравнение или вы работаете с буферами фиксированной длины.

  • strncat: Безопасная версия strcat. Позволяет ограничить количество символов, которые будут добавлены к целевой строке, тем самым предотвращая переполнение.

  • strchr: Ищет первое вхождение указанного символа в строке и возвращает указатель на это место или NULL, если символ не найден.

  • strstr: Ищет первое вхождение подстроки внутри другой строки и возвращает указатель на начало найденной подстроки или NULL, если подстрока не найдена.

## Практический пример использования

Давайте посмотрим, как некоторые из этих функций работают вместе:

#include <stdio.h>
#include <string.h> // Не забудьте включить для работы со строковыми функциями

int main() {
    char str1[50] = "Hello"; // Объявляем массив достаточного размера
    char str2[] = "World";

    strcat(str1, " "); // Добавляем пробел к str1
    strcat(str1, str2); // Добавляем str2 к str1

    printf("Result: %s\n", str1); // Вывод: "Hello World"
    printf("Length: %zu\n", strlen(str1)); // Вывод: "Length: 11" (5 + 1 + 5)

    return 0;
}

## Важные замечания при работе со строками в C

  • Нулевой символ (`0`): Все строки в стиле C должны заканчиваться нулевым символом \0. Это указывает функциям библиотеки строк, где строка заканчивается. Если его нет, функции будут читать память за пределами выделенного массива, что может привести к непредсказуемому поведению программы и ошибкам.

  • Предотвращение переполнения буфера: Это одна из самых распространенных и опасных проблем при работе со строками в C. Всегда убеждайтесь, что целевой буфер достаточно велик для размещения всех данных. Использование функций с префиксом strn (например, strncpy, strncat) — это хороший способ уменьшить риск переполнения.

  • Чувствительность к регистру: Помните, что большинство строковых функций (например, strcmp) чувствительны к регистру. Для сравнения без учета регистра вам могут понадобиться другие функции (например, strcasecmp на некоторых системах) или преобразование строк к одному регистру перед сравнением.