## Строки в языке C Для представления строк в языке C используются массивы типа `char`. Это единственный вид массива, который можно вводить и выводить не по циклу. **Описание, инициализация:** ```c char str1[100] = "Text1"; char str2[] = "Text2"; char str3[] = {'T', 'e', 'x', 't', '3', '\0'}; char* str4[] = "Text4"; ``` Признаком конца строки является т. н. **ноль-символ** - символ с кодом `0`. В случае, если при инициализации (примеры 1, 2, 4) или при вводе строка задаётся целиком, нулевой символ добавляется в конец строки автоматически. Если же массив типа `char` задаётся поэлементно (пример 3), то ноль-символ нужно указывать явно. ```c sizeof(str1); // размер строки ``` В примере 4 видно, что строку можно хранить через указатель, аналогично одномерному динамическому массиву. `sizeof` указателя - 4 байта. Помимо управляющего ноль-символа - признака конца строки - могут присутствовать и другие: - `\a` - звонок - `\t` - горизонтальная табуляция - `\r` - возврат каретки; - `\n` - перевод строки - `\b` - "забой" (backspace) - `\'` - апостроф - `\"` - двойная кавычка - `\\` - обратный слэш - `\0` - ноль-символ #### Ввод-вывод строк **Ввод:** 1. `cin` ```cpp int main() { char str[100]; cin >> str1; // читает до пробела cout << str1 << endl; } ``` 1. `gets` ```c int main() { char str[100]; gets(str1); // с пробелами cout << str1 << endl; } ``` **Вывод:** 1. `cout` ```cpp cout << dest; ``` 2. `puts` ```c int puts(const char* src); ``` #### Функции обработки строк Для работы со строками в языке C существует ряд стандартных функций: - `strcpy` - копирование `src` в `dest`: ```c char* strcpy(char* dest, const char* src); ``` - `strlen` - длина строки `src` (текста): ```c char* strlen(const char* src); ``` - `strcat` - соединение строк `dest` и `src` (`destsrc`): ```c char* strcat(char* dest, const char* src); ``` - `strchr` - находит первое вхождение символа `chr` в строке `src` и возвращает указатель на подстроку, начинающуюся с найденного символа: ```c char* strchr(const char* src, char chr); ``` - `strrchr` - то же, что и `strchr`, но последнее вхождение: ```c char* strrchr(const char* src, char chr); ``` - `strstr` - то же, только вхождение строки: ```c char* strstr(const char* str, const char* substr); ``` - `strcmp` - сравнивает `str1` и `str2`. Если равно - 0, если меньше - отрицательное число, если больше - положительное число: ```c char* strcmp(const char* str1, const char* str2); ``` - `strtok` - позволяет выделять из `src` отдельные слова (токены), используя в качестве разделителей символы из `seps`: ```c char* strtok(char* src, const char* seps); ``` - `atoi` - перевод строки `str` в целое число: ```c int atoi(const char* str); ``` - `atof` - перевод строки `str` в действительное число: ```c double atof(const char* str); ``` - `_itoa` - перевод целого числа в строку `dest` (`radix` - система счисления): ```c char* _itoa(int number, char* dest, int radix); ``` - `_gcvt` - перевод действительного числа в строку `dest`: ```c char* _gcvt(double number, int num_big, char* dest); ``` #### Примеры 1. Дана строка. Переписать ее в обратном порядке. ```c int main() { char str1[100] = "123456789", str2[100]; int n = strlen(str1); for (int i = 0; i < n; i++) { str2[n - i - 1] = str1[i]; } str[n] = '\0'; cout << str2 << endl; } ``` 2. Дана строка. Найти первое нахождение символа `6` в строке. ```c char str1[100] = "123456789"; char* str2 = strchr(str1, '6'); cout << str2 << endl; ``` 3. Даны 2 строки. Сравнить их. ```c char str1[100] = "Anna"; char str2[100] = "Anton"; cout << strcmp(str2, str1) << endl; ``` 4. Дана строка из слов, разделенных пробелами. Найти количество слов в строке. 1 вариант: ```c int main() { char str[100] = "Anna Anton Maxim"; int k = 0; for (int i = 0; i < strlen(str1); i++) { if (str1[i] == ' ') k++; } cout << k << endl; } ``` Данная программа не работает при наличии лишних пробелов. 2 вариант: ```c int main() { char str[100] = "Anna Anton Maxim"; int k = 0; for (int i = 0; i < strlen(str1); i++) { if (str1[i] != ' ' && str[i + 1] == ' ') k++; } cout << k << endl; } ``` Данная программа не работает при наличии других разделителей. 3 вариант: ```c int main() { char str[100] = "Vlad, Yura, Yousiff!"; char separators[] = " ,!"; int k = 0; char* token = strtok(str1, seps); while(token != null) { cout << token << endl; k++; token = strtok(NULL, seps); } cout << k << endl; } ``` 5. Дана строка, состоящая из слов. Определить, сколько слов представляют собой двоичные числа ```c int main() { char str1[100] = "1010111-Vlad, 111111, 0000Yura, 1010101, 111Yousiff! 1010f11, 00000"; char seps[] = " ,!-"; int k = 0; char* token = strtok(str1, seps); while (token != NULL) { cout << token << endl; bool f = true; for (int i = 0; i < strlen(token); i++) if (token[i] != '0' && token[i] != '1') f = false; if (f) k++; token = strtok(NULL, seps); } cout << k << endl; } ``` ## Тип данных `string` В C++ для работы со строками в консольных приложениях используется тип `string`, а в визуальных приложениях тип `String` (это 2 разных типа!). **Описание, инициализация:** ```cpp string s; s = "Text"; ``` ```cpp string s = "Text"; ``` ```cpp string s("Text"); ``` Доступ к элементу - по индексу: `s[5]`, `s[i]`. Для работы с типом `string` нужна библиотека ``. #### Операции - присваивания: `s1 = s2` - объединения строк: `s1 = s1 + s2` - сравнения строк: `s1 == s2`, `s1 != s2`, `s1 < s2`, `s1 <= s2`, `s1 > s2`, `s1 >= s2` #### Ввод данных 1. `cin >> s;` 2. `getline(cin, s);` #### Функции обработки строк 1. `s.length()` - длина строки 2. `s.substr(pos, length)` - подстрока длины `length`, начиная с `pos` 3. `s.empty()` - возвращает булевое значение пустоты троки 4. `s.insert(pos, s1)` - вставляет строку 5. `s.erase(pos, length)` - удаляет строку 6. `s.find(s1, pos)` - ищет строку `s1` с `pos` в `s` 7. `s.findfirst(s1, pos)` - номер первого вхождения символа `s1` в строке `s` #### Примеры ```cpp int main() { string str1, str2 = ""; cin >> str1; for (int i = 0; i < str1.length(); i++) str2 = str1[i] + str2; cout << str2 << endl; } ``` ```cpp int main() { string str1 = "AAAAAAA", str2 = "BBB"; str1.insert(3, str2); cout << str2 << endl; } ```