Разделы сайта:
Статьи по C и C++Стандартная библиотека CКнигиЮмор
Функции библиотеки string.h

Для обработки строк в программах, написанных на С, применяют билиотеку string.h. В нее входит достаточно большое количество функций. Перед использованием этой библиотеки следует ее подключить:

#include <string.h>

Создание строк
Для создания (не в памяти, а их инициализации) строк применяют функции strcpy и strcat, а также несколько их аналогов. Перед использованием функции strcpy (STRing CoPY) следует проверить, выделена ли память под обе строки. Объявление функции копирования строк:

char *strcpy(char *dest, const char *src);
wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);

char *strncpy(char *dest, const char *src, size_t maxlen);
wchar_t *wcsncpy(wchar_t *dest, const wchar_t *src, size_t maxlen);

Общее их значение таково: строка, находящаяся в src помещается в dest. Если Вы хотите ограничить количество копируемых символов (это бывает полезно, когда длина строки ограничена) следует использовать функцию strncpy. Функции возвращают указатель на полученную строку.

Для того, чтобы прибавить к строке другую, программисты используют функцию strcat (STRing conCATenate). Объявление функции добавления строк:

char *strcat(char *dest, const char *src);
wchar_t *wcscat(wchar_t *dest, const wchar_t *src);

Эти функции добавляют строку src в конец строки dest. За счет того, что функции возвращают указатель на полученную строку, имеется возможность использовать вложенные вызовы. Премер использования функций создания строк.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main() {
  char *s, *s1, *s2;
  s1 = strdup(" text0 ");
  s2 = strdup(" text1 ");
  s = malloc(128);
  *s="\0";    //Я инициализирую строки так это - 
  //намного быстрее вызовов strcpy 
  strcat(s,s1); //Функция strcat
  strcat(s,s2); 
  printf("%s\n", s);
  free(s1);
  free(s2);
  free(s);
  return 0;
}

Вы увидите на экране " text0 text1 text2 ". Здесь мы познакомились с функцией strdup (STRing DUPclicate, не определена стандартном C, однако легка в написании). Это аналог функции strcpy, но помимо копирования строки, она выделяет память и возвращает указатель на нее. Ее вызов эквивалентен вызовам malloc и strcpy, поэтому Про strdup надо написать следующее: блок памяти, выделенный для размещения дубликата строки, необходимо вручную удалять при помощи функции free. В string.h она объявлена так:

char *strdup(const char *s);
wchar_t *_wcsdup(const wchar_t *s);

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

  • Обобщенный вариант strcpy - memcpy.
  • Не следует злоупотреблять использованием функции strncpy, так как все символы, которые не достают до длины maxlen заполняет нулями, это может вызвать "притормаживание" программы.
  • Для того, чтобы проинициализировать строку, некоторые программисты копируют в нее пустую строку: strcpy(s, " "); Гораздо быстрее будет код: *s=0;
  • Вместо того, чтобы использовать strcat, можно вызвать функцию strcpy, а указатель переместить на конец строки.
  • Функции копирования (кроме strncpy) не проверяют длину строки. Размер приемника должен быть больше, чем размер источника на 1 символ (для нуль-терминатора).
  • Функция strdup не предусмотрена стандартами ANSI C.
  • При вызове функции strncpy следует помнить, что если длина копируемой строки превосходит параметр maxlen, то строка-получатель не будет завершена терминирующим символом(нулем). В этом случае такой символ надо ставить вручную.

Сравнее строк и поиск подстрок.
Сравнее строк представлено в С функциями strcmp, strncmp, strncmpi (strnicmp), strcmpi (stricmp). Следует заметить, что функции strcmpi и stricmp, а также strncmpi и strnicmp идентичны. Самый простой способ сравнить две строки, использовать функцию strcmp (STRing CoMPare). Эта функция сравнивает две строки без учета регистра. Протитипы функций выглядят так:

int strcmp(const char *s1, const char *s2);
int wcscmp(const wchar_t *s1, const wchar_t *s2);

Для всех функций сравнения существует единое правило возращаемого значения:

РезультатВозвращаемое значение
Строка s1 меньше строки s2<0
Строка s1 равна строке s20
Строка s1 больше строки s2>0

Для того, чтобы сравнивать строки c учетом регистра, следует использовать функцию stricmp или strcmpi. Следует сделать важную оговорку: регистр определяется только для латиницы. Объявлена эта функция так:

int stricmp(const char *s1, const char *s2);
int _wcsicmp(const wchar_t *s1, const wchar_t *s2);

int strcmpi(const char *s1, const char *s2);

Я не оговариваю возвращаемые значения этих функций, так как они такие же, как и для strcmp. Если вы хотите ограничить количество сравниваемых символов, используйте функции с содержащие в названии букву 'n':

int strncmp(const char *s1, const char *s2, size_t  maxlen);
int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t  maxlen);


/* Без учета регистра */
int strncmpi(const char *s1, const char *s2, size_t n);
int wcsncmpi(const wchar_t *s1, const wchar_t *s2, size_t n);

Для того, чтобы найти какую-то подстроку в данной строке, необходимо использовать функции strstr (общая) и strchr (для символов), strspn, strpbrk. Для того, чтобы найти подстроку, программисты обычно используют функцию strstr (STRing in STRing). Объявлена она так:

char *strstr(const char *s1, const char *s2);                

Главное замечание состоит в том, что эти прототипы верны только для С, в С++ первый параметр объявляется без спецификатора const. Возвращает эта функция указатель на первое вхождение s2 в s1 или NULL, если s2 не содержится в s1. Если вам необходимо найти не подстроку, а один из символов строки, используйте функцию strchr (STRing includes CHaR). Ее прототип:

/* Для С */
char *strchr(const char *s, int c); 
//Для С++
const char *strchr(const char *s, int c);     //или
char *strchr( char *s, int c);
wchar_t *wcschr(const wchar_t *s, int c);

Эта функция возвращает указатель на первое вхождение символа c в s. Для нахождения последнего вхождения этого символа, применяйте strrchr. Если Вам необходимо найти один из множества символов, используйте функцию strpbrk. Как и у strchr, для С и С++ прототип разный.

/* C */
char *strpbrk(const char *s1, const char *s2);
//C++
const char *strpbrk(const char *s1, const char *s2);
char *strpbrk(char *s1, const char *s2);
wchar_t * wcspbrk(const wchar_t *s1, const wchar_t *s2);

Возвращаемым значением является указатель на первое вхождение одного из символов из s2 в строку s1.

Функция strspn объявлена так:

size_t strspn(const char *s1, const char *s2);
size_t wcsspn(const wchar_t *s1, const wchar_t *s2);
Эта функция возвращает число первых символов, строки s1, которые входят в множество символов s1 (последовательность безразлична).

Функция strcspn возвращает индекс первого символа в s1, который принадлежит множеству символов s2.

size_t strcspn(const char *s1, const char *s2);
size_t wcscspn(const wchar_t *s1, const wchar_t *s2);

Общие замечания.

  • Есть способ избежать вызова strcmp, если сначала сравнить первые символы. В таком случае, если они не равны, то одна строка не соответствует другой.
  • Как я уже сказал, регистр в strcmpi и т. п. функциях определяется только для латиницы.
  • По традициям С, в функциях обработки символов используется тип int, хотя если число будет больше 128 (255), функция будет работать с ошибкой.

Прочие функции
Для того, чтобы вычислить длину строки, следует использовать функцию strlen (STRing LENgth) вместо оператора sizeof.

size_t strlen(const char *s);
size_t wcslen(const wchar_t *s);
Возвращает эта функция длину строки s. Иногда функцию strlen используют в циклах, в качестве ограничивающего аргумента. Если Вы хотите оптимизировать свой код, Вам необходимо заранее сосчитать длину строки, а затем использовать полученную переменную в цикле. Это позволит Вам сэкономить время на вызов функции и подсчет длины. Если длина не статична, можно менять полученную переменную в цикле. Если Вам необходимо проверить строку на наличие в ней символов, не обязательно пользоваться функцией strlen. Достаточно проверить первый символ: *s==0 вместо strlen(s)==0.

Для того, чтобы перевернуть строку, используйте функцию strrev (STRing REVerse).

char *strrev(char *s);
wchar_t *_wcsrev(wchar_t *s);
Функция возвращает указатель на перевернутую строку.

Для того, чтобы заполнить строку символами (например тире), достаточно вызова strnset.

char *strnset(char *s, int ch, size_t n);
wchar_t *_wcsnset(wchar_t *s, wchar_t ch, size_t n);
Возвращается указатель на buf, заполненный символом ch длиной в n символов.

Для того, чтобы изменить регистр букв в строке применяются функции strlwr и strupr (только латиница). Прототип функции strlwr (STRing LoWeR).

char *strlwr(char *s);
wchar_t *_wcslwr(wchar_t *s);
Перед их использванием надо корректно настроить локаль.

Прототип функции strupr (STRing UPpeR).

char *strur(char *s);
wchar_t *_wcsupr(wchar_t *s);
Эти функции возвращают указатель на s.

Что не вошло в эту статью?
Во-первых, сюда не вошло описание работы со строками, как с массивами char (создание в памяти). Во-вторых не вошли функции strtok (STRing TOKen), strtol и другие функции конвертации строк. В-третьих, здесь описана работа со строками только с gомощью стандартных библиотек С.

Автор: Кляус Сергей aka myaut(Мяут).
Огромное человеческое спасибо Adil и trainer за помощь в подготовке материала.
Автор и разработчик сайта - Кляус Сергей. Спасибо Форуму на Исходниках.RU за помощь в сборе материалов.
X