string.h

====== Библиотека обработки строк string.h ======
Здесь мы перечислим основные функции, предназначенные для работы со строками. Большинство прототипов этих функций (если не оговорено особо) находится в заголовочном файле string.h.


Строковые функции, в имени которых содержится дополнительная буква n, объявляют числовой параметр, ограничивающий некоторым образом действие функции. Эти функции безопаснее, но медленнее, чем их аналоги, не содержащие букву n. Программные примеры содержат следующие пары функций: strcpy() и strncpy(), strcat() и strncat(), strcmp() и strncmp().

* int getchar(); – Возвращает значение символа(если он есть), который пользователь набрал на клавиатуре. После ввода символа нужно нажать клавишу Enter. Заголовочный файл – stdio.h
* int getch(); – Аналогично предыдущему, только символ на экране не отображается. Используется чаще для организации задержки выполнения программы. Заголовочный файл – conio.h
* int putchar(int c); – Выводит символ c на экран. В случае успеха возвращает сам символ c, в противном случе – EOF. Заголовочный файл – stdio.h
* char *gets(char *s); – Читает символы, включая пробелы и табуляции, до тех пор, пока не встретится символ новой строки, который заменяется нулевым символом. Последовательность прочитанных символов запоминается в области памяти, адресуемой аргументом s. В случае успеха возвращает аргумент s, в случае ошибки – нуль. Заголовочный файл – stdio.h
* int puts(const char *s); – Выводит строку, заданную аргументом const char *s. Заголовочный файл – stdio.h
* char ***strcpy** (char *dst, const char *src); dst — указатель ([[pointer]]) на буфер назначения. src — указатель ([[pointer]]) на исходную строку. Копировать одну строку в другую. Аналогичная функция [[wpru>strncpy]]() ограничивает количество копируемых символов. Источник (source) и приемник (destination) являются указателями типа char * или символьными массивами.
* char ***strcat**(char *dest, const char *scr); – Объединяет исходную строку scr и результирующую строку dest, присоединяя первую к последней. Возвращает dest.
* char *strncat(char *dest, const char *scr, int maxlen); – Объединяет maxlen символов исходной строки scr и результирующую строку dest, присоединяя часть первой к последней. Возвращает dest.
* char *strchr(const char *s, int c); – Ищет в строке s первое вхождение символа c, начиная с начала строки. В случае успеха возвращает указатель на найденный символ, иначе возвращает нуль.
* char *strrchr(const char *s, int c); – Аналогично предыдущему, только поиск осуществляется с конца строки.
* int strcmp(const char *s1, const char *s2); – Сравнивает две строки. Возвращает отрицательное значение, если s1<s2; нуль, если s1==s2; положительное значение, если s1>s2. Параметры – указатели на сравниваемые строки.
* int stricmp(const char *s1, const char *s2); – Аналогично предыдущему, только сравнение осуществляется без учета регистра символов.
* int strncmp(const char *s1, const char *s2, int maxlen); – Аналогично предыдущему, только сравниваются первые maxlen символов.
* int strnicmp(const char *s1, const char *s2, int maxlen); – Аналогично предыдущему, только сравниваются первые maxlen символов без учета регистра.
* int strcspn(const char *s1, const char *s2); – Возвращает длину максимальной начальной подстроки строки s1, не содержащей символов из второй строки s2.
* int **strlen**(const char *s); – Возвращает длину строки s – количество символов, предшествующих нулевому символу. **wcslen** использовать для wchar_t (юникода).
* char *strlwr(char *s); – Преобразует все прописные (большие) буквы в строчные (малые) в строке s.
* char *strupr(char *s); – Преобразует все строчные (малые) буквы в прописные (большие) в строке s.
* char *strnset(char *s, int c, int n); – Заполняет строку s символами c. Параметр n задает количество размещаемых символов в строке.
* char *strpbrk(const char *s1, const char *s2); – Ищет в строке s1 первое вхождение любого символа из строки s2. Возвращает указатель на первый найденный символ или нуль – если символ не найден.
* char *strrev(char *s); – Изменяет порядок следования символов в строке на обратный (кроме завершающего нулевого символа). Функция возвращает строку s.
* char *strset(char *s, int c); – Заменяет все символы строки s заданным символом c.
* int strspn(const char *s1, const char *s2); – Вычисляет длину максимальной начальной подстроки строки s1, содержащей только символы из строки s2.
* char *strstr(const char *s1, const char *s2); – Ищет в строке s1 строку s2. Возвращает адрес первого символа вхождения строки s2. Если строка отсутствует – возвращает нуль.
* char *strtok(char *s1, const char *s2); – Делит исходную строку s1 на лексемы (подстроки), разделенные одним или несколькими символами из строки s2.<file>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
int main() {
char str[] = "dfaghs8da111adf56756wa7ghedh";
char delim[] = "a87";//что мы считаем разделителями в строке
char *word = NULL;
 
word = strtok(str,delim);// первый раз вызываем с явным указанием строки,
//для дальнейшего поиска в заданной строке пишем NULL
while (word = strtok(NULL,delim))
cout<<word<<endl;
}
 
$ ./tststrtok
ghs
d
111
df56
56w
ghedh
</file>

* double atof(const char *s); – Преобразует строку s в число с плавающей точкой типа double. Заголовочный файл – math.h
* int atoi(const char *s); – Преобразует строку s в число типа int. Возвращает значение или нуль, если строку преобразовать нельзя. Заголовочный файл – stdlib.h
* long atol(const char *s); – Преобразует строку s в число типа long. Возвращает значение или нуль, если строку преобразовать нельзя. Заголовочный файл – stdlib.h
* char *itoa(int value, char *s, int radix); – Преобразует значение целого типа value в строку s. Возвращает указатель на результирующую строку. Значение radix – основание системы счисления, используемое при преобразовании (от 2 до 36). Заголовочный файл – stdlib.h<file>
#include <iostream>
#include <string.h>
using namespace std;

void main()
{
char *w2itoa = NULL;
char s11[200]; //выделяем память под строку
w2itoa = itoa(43534, s11, 16);
cout<<w2itoa<<“\n”;
}</file>

====== Конкатенация строк ======
Конкатенация двух строк означает их сцепление, при этом создается новая, более длинная строка. При объявлении строки
char original[128] = “Test “;
оператор
strcat(original, ” one, two, three!”);
превратит значение первоначальной строки original в “Test one, two, three!”

При вызове функции strcat() убедитесь, что первый аргумент типа char * инициализирован и имеет достаточно места, чтобы запомнить результат. Если c1 адресует строку, которая уже заполнена, а c2 адресует ненулевую строку, оператор strcat(c1, c2); перезапишет конец строки, вызвав серьезную ошибку.

Функция strcat() возвращает адрес результирующей строки (совпадающий с ее первым параметром) и может использоваться как каскад нескольких вызовов функций:
strcat(strcat(c1,c2),c3)
Следующий пример показывает, как можно использовать функцию strcat() для получения в одной строке фамилии, имени и отчества, хранящихся отдельно, например, в виде полей базы данных. Введите фамилию, имя и отчество. Программа сцепит введенные вами строки и отобразит их как отдельную строку.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<file>
#include <iostream>
#include <string.h>
using namespace std;
void main()
{
//Резервирование места для ввода трех строк.
char *fam = new char[128];
char *im = new char[128];
char *otch = new char[128];
//Ввод данных.
cout << "Enter" << "\n";
cout << "\tSurname: ";
cin >> fam;
cout << "\tName: ";
cin >> im;
cout << "\tLastname: ";
cin >> otch;
//Резервирование места для результата.
//Нужно учесть два пробела и результирующий
//нулевой символ.
char *rez=new char[strlen(fam)+strlen(im)+strlen(otch)+3];
//"Сборка" результата.
strcat(strcat(strcpy(rez,fam)," "),im);
strcat(strcat(rez," "),otch);
//Возврат памяти в кучу.
delete [] fam;
delete [] im;
delete [] otch;
//Вывод результата.
cout << "\nResult: " << rez;
delete [] rez;
}
</file>

Приведенная программа демонстрируют важный принцип конкатенации строк: всегда инициализируйте первый строковый аргумент. В данном случае символьный массив rez инициализируется вызовом функции strcpy(), которая вставляет fam в rez. После этого программа добавляет пробелы и две другие строки – im и otch. Никогда не вызывайте функцию strcat() с неинициализированным первым аргументом.

Если вы не уверены в том, что в строке достаточно места для присоединяемых подстрок, вызовите функцию strncat(), которая аналогична функции strcat(), но требует числового аргумента, определяющего число копируемых символов. Для строк s1 и s2, которые могут быть либо указателями типа char *, либо символьными массивами, оператор

strncat(s1, s2, 4);

присоединяет максимум четыре символа из s2 в конец строки s1. Результат обязательно завершается нулевым символом.

Существует один способ использования функции strncat(), гарантирующий безопасную конкатенацию. Он состоит в передаче функции strncat() размера свободной памяти строки-приемника в качестве третьего аргумента. Рассмотрим следующие объявления:
<file>
const int MAXLEN=128
char s1[MAXLEN] = “Cat”;
char s2[] = “in hat”;
</file>
Вы можете присоединить s2 к s1, формируя строку “Cat in hat”, с помощью функции strcat():
strcat(s1, s2);
Если вы не уверены, что в s1 достаточно места, чтобы запомнить результат, используйте альтернативный оператор:
strncat(s1, s2, (MAXLEN-1)-strlen(s1));
Этот способ гарантирует, что s1 не переполнится, даже если s2 нужно будет урезать до подходящего размера. Этот оператор прекрасно работает, если s1 – нулевая строка.

Часто программам приходится выполнять поиск в строках отдельных символов или подстрок, особенно при проверке имен файлов на заданное расширение. Например, после того как пользователю предложили ввести имя файла, проверяется, ввел ли он расширение .ТХТ, и если это так, то выполняется действие, отличное от того, какое было бы выполнено для расширения .ЕХЕ.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
void main()
{
char *filename = new char[128];
cout << "Enter name of file: ";
gets(filename);
cout << "\nName of file: " << filename << "\n";
if (strchr (filename,'.'))
cout << "Name has extension" << "\n";
else
strcat (filename,".TXT");
cout << "Name of file: " << filename << "\n";
delete [] filename;
}
</file>
Данная программа находит расширение в имени файла, выполняя поиск точки среди символов введенной строки. (В имени файла может быть только одна точка, которая должна предшествовать расширению, если оно имеется.) Ключевым в этой программе является оператор
<file>
if (strchr (filename,'.'))
cout << "Name has extension" << "\n";
else
strcat (filename,".TXT");
</file>

Выражение strchr (filename,’.’) возвращает указатель на символ точки в строке, адресуемой указателем filename. Если такой символ не найден, функция strchr() возвращает нуль. Поскольку ненулевые значения означают “истину”, вы можете использовать функцию strchr() в качестве возвращающей значение “истина”/”ложь”. Вы также можете применить функцию strchr() для присваивания указателя на подстроку, начинающуюся с заданного символа. Например, если р – указатель, объявленный как char *, и указатель filename адресует строку TEST.ТХТ, то результат действия оператора p=strchr(filename, ‘.’); показан на рисунке
{{:arrchar7.jpg|}}

Рисунок демонстрирует еще один важный момент, связанный с адресацией указателем не полной строки, а ее части – подстроки. Такими указателями следует пользоваться с большой осторожностью. На рисунке показана только одна строка, TEST.ТХТ, оканчивающаяся нулевым байтом, но два указателя – filename и p. Указатель filename адресует полную строку. А указатель p адресует подстроку внутри того же набора символов. Строковые функции не заботятся о байтах, которые предшествуют их первому символу. Поэтому оператор
puts(p);
отображает подстроку .ТХТ так, будто она полная строковая переменная, а не часть другой строки.

В программировании на C нет ничего необычного в использовании многих указателей, адресующих подстроки одной и той же полной строки. Но строка, показанная на рисунке, расположена в куче, поэтому оператор

delete [] p;

пытаясь тем самым освободить подстроку, адресуемую указателем p, что, несомненно, приведет к разрушению кучи, вызвав ошибку, относящуюся к разряду трудно обнаруживаемых.

Функция strchr() отыскивает первое появление символа в строке. Объявления и операторы
<file>
char *p;
char s[]=”Abracadabra”;
p = strchr(s,’a’);
</file>
присваивают указателю p адрес первой строчной буквы ‘а’ в строке “Abracadabra”.

Функция strchr() рассматривает завершающий нуль строки как значащий символ. Приняв во внимание этот факт, можно узнать адрес конца строки. Учитывая предыдущие объявления, оператор

p = strchr(s,0);
установит указатель p равным адресу подстроки “bra” в конце строки “Abracadabra”.
====== Поиск подстрок ======
Кроме поиска символов в строке, вы также можете поохотиться и за подстроками. Этот пример демонстрирует этот метод. Данная программа аналогична предыдущей, но устанавливает расширение файла .ТХТ.
<file>
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
void main()
{
char *filename = new char[128],*p;
cout << “Enter name of file: “;
gets(filename);
cout << “\nName of file: ” << filename << “\n”;
strupr(filename);
p = strstr (filename,”.TXT”);
if (p)
cout << “Name has extension” << “\n”;
else
{ p = strchr (filename,’.’);
if (p)
*p=NULL; //Удалить любое другое расширение.
strcat (filename,”.TXT”);
}
cout << “Name of file: ” << filename << “\n”;
delete [] filename;
}
</file>
Эта программа создает имя файла, которое обязательно заканчивается расширением .ТХТ. Чтобы определить, есть ли в имени файла это расширение, программа выполняет оператор
p = strstr (filename,”.TXT”);
Подобно strchr(), функция strstr() возвращает адрес подстроки или нуль, если искомая строка не найдена. Если же цель будет обнаружена, указатель p установится равным ее адресу, в данном примере – адресу точки в подстроке .ТХТ. Поскольку расширение может быть введено и строчными буквами, программа выполняет оператор
strupr(filename);
чтобы перед вызовом функции strstr() преобразовать буквы оригинальной строки в прописные.

Пример также демонстрирует способ усечения строки в позиции заданного символа или подстроки. Здесь вызывается функция strstr(), чтобы установить указатель p равным адресу первой точки в строке filename. Если результат этого поиска не нулевой, то выполнится оператор, который запишет вместо точки нулевой байт: <file>
*p = NULL;
</file>
Тем самым будет присоединен новый конец строки в том месте, где раньше находилось расширение файла. Теперь строка готова к добавлению нового расширения путем вызова функции strcat().
====== Копирование строк ======
Оператор присваивания для строк не определен. Если с1 и с2 – символьные массивы, вы не сможете скопировать один в другой следующим образом:
с1 = с2; //???
Но если с1 и с2 объявить как указатели типа char *, компилятор согласится с этим оператором, но вряд ли вы получите ожидаемый результат. Вместо копирования символов из одной строки в другую оператор с1 = с2 скопирует указатель с2 в указатель с1, перезаписав, таким образом, адрес в с1, потенциально потеряв информацию, адресуемую указателем.

Чтобы скопировать одну строку в другую, вместо использования оператора присваивания вызовите функцию копирования строк strcpy(). Для двух указателей с1 и с2 типа char * оператор
strcpy(с1, с2);
копирует символы, адресуемые указателем с2, в память, адресуемую указателем с1, включая завершающие нули. И только на вас лежит ответственность за то, что принимающая строка будет иметь достаточно места для хранения копии.

Аналогичная функция strncpy() ограничивает количество копируемых символов. Если источник (source) и приемник (destination) являются указателями типа char * или символьными массивами, то оператор
strncpy(destination, source, 10);
скопирует до 10 символов из строки, адресуемой указателем source, в область памяти, адресуемую указателем destination. Если строка source имеет больше 10 символов, то результат усекается. Если же меньше – неиспользуемые байты результата устанавливаются равными нулю.