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

В различных языках программирования предусмотрены специализированные функции для манипуляции строками. Это избавляет разработчика от необходимости создавать свои собственные решения. Например, одна из часто встречающихся задач - вычисление длины строки. Для этого во многих языках уже есть такие встроенные функции.

В языке программирования C, функции для работы со строками находятся в заголовочном файле string.h, который обязательно нужно подключать к своему коду. Там можно обнаружить около двадцати строковых функций. Среди них можно выделить функции для поиска символов, сравнения и копирования строк и даже более специализированные. Подробная информация о многих из этих функций представлена в приложении книги Б. Кернигана и Д. Ритчи "Язык программирования C. Второе издание".

Функции, которые объявлены в string.h, могут изменять одну из переданных строк по указателю. Такое поведение зависит от предназначения функции. Чаще всего они возвращают что-то: либо указатель на символ, либо целое число. В случае, если вы вызываете функцию ради изменения параметра, то возвращаемое значение можно просто проигнорировать.

К примеру, рассмотрим функцию strcpy(), которая объявлена как char *strcpy (char *, const char*). Она копирует строку, указанную вторым параметром, в ту, что указана первым параметром, тем самым изменяя первый параметр, и возвращает указатель на первый символ этой строки:

	char s1[10], s2[10];
	char *s3;
	s3 = s2;
 
	gets(s1);
	s3 = strcpy(s2,s1);
	puts(s2);
	puts(s3);
	printf("%p, %p\n", s2, s3);

В этом примере переменные s2 и s3 указывают на один и тот же элемент, что подтверждается одинаковыми адресами, выводимыми функцией printf(). При этом значение, возвращаемое strcpy(), нельзя присвоить массиву. Обычной практикой является игнорирование результата, поскольку чаще всего достаточно изменения одной из строк по указателю.

Наоборот, функции типа strlen() или strcmp() не меняют параметры, они вызываются именно ради их результата. Например, функция strcmp() сравнивает строки-аргументы посимвольно и возвращает 0, -1 или 1. Если выполнить вызов strcmp("boy", "body"), результатом будет 1, так как 'y' лексикографически больше 'd'. Тогда как вызов strcmp("body", "boy") вернет -1, так как первая строка меньше второй.

Функция strtok()

С помощью функции strtok() можно разбивать строку на отдельные лексемы. Объявление этой функции следующее: char *strtok (char *, const char *). На первом вызове первым параметром передается строка, которую нужно разбить, а вторым — строка-разделитель. Для дальнейших вызовов для этой же строки первым параметром следует указывать NULL, так как функция хранит внутреннее состояние. Вот пример кода:

	char str[] = "one, two, three, four, five";
	char *sp;
 
	sp = strtok(str, ", ");
	while (sp) {
		puts(sp);
		sp = strtok(NULL, ", ");
	}

В результате выполнения данного фрагмента кода на экране появится список слов в столбик:

one
two
three
four
five

При первом вызове strtok(), функция получает указатель на первый элемент массива со строкой и саму строку-разделитель. После этого массив str изменяется, оставаясь с одним только словом "one". Функция возвратит указатель на это слово, чтобы его можно было присвоить переменной sp.

Хотя вызывающая функция теряет остаток массива, strtok() сохраняет указатель на этот остаток. Если в следующих вызовах передан NULL, функция использует уже сохраненный "хвост".

Копирование частей строк

При необходимости объединить две строки можно использовать функцию strcat(), которая добавляет вторую строку в конец первой. Аналогичная функция strncat() присоединяет n символов второй строки к первой, где n передается как третий параметр.

А как быть, если задача более сложная? Например, требуется соединить начало одной строки с концом другой. Это можно сделать с помощью функций копирования, таких как strcpy(). Вот как это работает:

	char s1[20] = "Peter Smith", s2[] = "Julia Roberts";
	strcpy(s1+5, s2+5);
	puts(s1);

В этом примере на экране отобразится "Peter Roberts". Это произошло потому, что указатель передан на шестой символ первой строки. Вследствие этого функции strcpy() замещают символы первой строки только начиная с шестого, так как о предыдущих она ничего не знает. Вторая строка копируется начиная с соответствующего места.

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

	char s1[20] = "one three", s2[20] = "two";
	strcpy(s2+3, s1+3);
	strcpy(s1+4, s2);
	puts(s1);

В этом примере концевые символы из первой строки сначала копируются во вторую, получится "two three". Затем в первую строку, пропустив начало, добавляется вторая строка.

Описание некоторых функций для работы со строками

Задание:

Ниже представлены описания некоторых функций, выполняющих операции над строками. Придумайте и напишите маленькие программы, иллюстрирующие работу этих функций.

  • char *strchr (const char *, int c). Возвращает указатель на первое вхождение символа с в строку. Возвращает NULL, если такого символа в строке нет.
  • char *strstr (const char *s2, const char *s1). Возвращает указатель на первое вхождение строки s1 в строку s2. Если совпадений нет, возвращает NULL.
  • char *strncpy (char *, const char *, size_t n). Копирует n символов второй строки в первую.
  • size_t strspn (const char *, const char *). Возвращает длину начала первой строки, в которую входят символы, из которых состоит вторая строка.

Вопросы для самопроверки:

  1. В каком заголовочном файле находятся функции для работы со строками в языке программирования C?
  2. Что делает функция strcpy() и какие параметры она принимает?
  3. Каковы характеристики работы функции strcmp() и какие значения она может возвращать?
  4. Опиши процесс, как функция strcat() используется для объединения строк.
  5. Как функция strchr() используется для поиска символа в строке, и что она возвращает, если символ не найден?
  6. Как работает функция strspn() и что она возвращает?

Программа курса:

  1. Описание курса
  2. Введение в язык программирования C
  3. Типы данных в C и форматированный вывод
  4. Символьные типы и управляющие символы в C
  5. Операторы ветвления и switch в C
  6. Циклы и операторы в языке C
  7. Битовые операции в языке C
  8. Посимвольный ввод и вывод в C - буферизация
  9. Переменные, адреса и указатели в C
  10. Передача аргументов по ссылке и значению в C
  11. Форматированный ввод данных с использованием scanf
  12. Генерация псевдослучайных чисел на C
  13. Адресная арифметика в массивах C
  14. Передача массивов в функции и указатели
  15. Строки в языке C - особенности и функции работы
  16. Функции работы со строками в C
  17. Работа со структурами в C - создание и применение
  18. Динамические структуры данных в C
  19. Ввод и вывод данных из файлов в языке C
  20. Передача аргументов в C и работа с файлами
  21. Препроцессор в языке C - директивы и макросы
  22. Создание и компиляция многофайловых программ в C
  23. Использование статических и динамических библиотек в C