Функции для обработки строк в языке C
Особенности функций для работы со строками
Языки программирования могут включать специальные функции для работы со строками, избавляя тем самым программиста от необходимости писать собственные функции обработки строк. Например, часто требуется определить длину строки, и поэтому в языках предусмотрена функция, измеряющая ее длину.
В языке программирования C функции для работы со строками объявляются в заголовочном файле string.h
, который надо не забывать подключать к своему исходному коду. Существует около двадцати функций для работы со строками. Среди них есть те, которые осуществляют поиск символов в строке, функции сравнения, копирования строк, а также более специфические. Перечень и описание большинства функций можно найти в приложении книги Б. Кернигана, Д. Ритчи "Язык программирования C. Второе издание".
Все функции, объявленные в string.h
, в процессе своей работы могут изменять или не изменять одну из переданных по указателю строк. Это зависит от назначения функции. Однако большинство из них что-то возвращают: либо указатель на символ, либо целое. При этом если функция меняет один из своих параметров и ради этого была вызвана, тогда то, что она возвращает, можно проигнорировать (т.е. ничему не присваивать в вызывающей функции).
Например, функция strcpy
имеет такое объявление: char *strcpy (char *, const char*)
. Она копирует строку, на которую указывает второй параметр, в строку, на которую указывает первый параметр. Таким образом первый параметр изменяется. Кроме того, функция возвращает указатель на первый символ строки:
char s1[10], s2[10]; char *s3; fgets(s1, sizeof(s1), stdin); s3 = strcpy(s2, s1); printf("%s", s2); printf("%s", 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"; 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"; char s2[] = "Julia Roberts"; strcpy(s1+5, s2+5); puts(s1);
В данном случае на экране будет выведено "Peter Roberts". Почему так произошло? В функцию strcpy()
был передан указатель на шестой символ первой строки. Это привело к тому, что при копировании символы этой строки затираются только начиная с 6-го, т.к. strcpy()
о предыдущих символах ничего не "знает". В качестве второго аргумента также передается только часть строки, которая и копируется в первую.
Как вставить одну строку в середину другой? Можно решить эту задачу, используя третью "буферную" строку, куда можно сначала скопировать первую строку, потом вторую, затерев конец первой, потом присоединить конец первой. Но можно поступить и так:
char s1[20] = "one three"; char 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 *)
. Возвращает длину начала первой строки, в которую входят символы, из которых состоит вторая строка.
Придумайте примеры, иллюстрирующие работу функций strchr
, strstr
, strncpy
.
Курс с решением задач:
pdf-версия