- Символьный тип данных
В C++ символьный тип данных char
относится к целым типам, так как в переменной типа char
скрывается, на самом деле, код символа в кодовой таблице (ASCII). Размер памяти отводимой на хранение объекта типа char
– 1 байт. Напомним, что это позволяет хранить значения в диапазоне от 0 до 255. Этого достаточно, чтобы закодировать все символы ASCII (“аски”). Вывод символов по их кодам можно осуществить так:
Программа 9.1
#include <iostream> using namespace std; int main() { for(int i = 33; i <= 127; i++) cout << i << '\t' << char(i) << endl; return 0; }
В программе используется явное преобразование типов: int → char
.
Объявление и инициализация переменной типа char
:
char c = 'A';
Символьным литералом является один или два символа заключённые в одинарные кавычки (апострофы). Например: 'q'
, 'Я'
, '\n'
, '\t'
.
Управляющие последовательности используются для описания определённых специальных символов внутри строковых литералов.
Некоторые управляющие последовательности:
\' одинарная кавычка \" двойная кавычка \? вопросительный знак \\ обратный слеш \0 нулевой символ \n перевод строки - новая строка \t горизонтальная табуляция \v вертикальная табуляция
Мы уже применяли символ '\n'
для перевода на новую строку при выводе прямоугольных таблиц, например, матриц.
Манипулятор endl
, также осуществляет перевод на новую строку, но, в тоже время, производит сброс буфера вывода (а следовательно и всех форматов при использовании манипуляторов). Поэтому, для сохранения формата, там где нужно производить переход на новую строку, можно использовать '\n'
.
Строка в С++ – это массив символов, в котором последний элемент имеет значение '\0'
(нулевой символ). Это значение является признаком конца строки. Символьный массив не является строкой если он не заканчивается нулевым символом.
Способ инициализации строки, как массива не является удобным:
char str1[] {'Э', 'т', 'о', ' ', 'с', 'т', 'р', 'о', 'к', 'а', '!', '\0'};
Инициализировать строку можно более простым способом, заключив её в двойные кавычки:
char str2[] = "Это тоже строка!";
В этом случае добавлять нулевой символ не нужно. При вводе символьного массива (далее символьной строки) с клавиатуры нулевой символ также будет добавлен автоматически.
Использование потока cin
для инициализации символьной строки:
const int buf = 80; char myStr[buf]; cout << "Введите строку: "; cin >> myStr;
В этом фрагменте константой buf
определяется размер массива. Необходимо помнить, что в С++ отсутствует контроль выхода за границы массива. Также необходимо помнить о том, что размер массива должен быть достаточен для включения нулевого символа. Существует возможность ограничить количество вводимых символов с помощью манипулятора setw()
:
cin >> setw(buf) >> myStr;
Если будет введена строка, содержащая пробелы, то первый же пробел оператор извлечения (>>
) будет считать нулевым символом и отправит в массив только символы предшествующие пробелу, а все остальное будет оставлено на очереди в потоке (который, следовательно, потребуется очистить).
Программа 9.2.
#include <iostream> #include <iomanip> using namespace std; int main() { const int buf = 80; char myStr[buf]; cout << "Введите строку: "; cin >> setw(buf) >> myStr; cout << "Вы ввели строку: " << endl << myStr << endl; return 0; }
Введите строку: Это моя первая строка Вы ввели строку: Это
Для чтения строки, имеющей символы пробела, необходимо использовать функцию get()
. Эта функция является методом класса istream
, поэтому вызывается как функция-член этого класса: cin.get()
. Исправим программу 9.2:
const int buf = 80; char myStr[buf]; cout << "Введите строку: "; cin.get(str, buf); cout << "Вы ввели строку: " << endl << myStr << endl;
get()
и getline()
1. Функция get()
cin.get() cin.get(str, buff)
Функция get()
считывает символы в массив, но оставляет нулевой символ в потоке ввода. Функция get()
имеет два аргумента: имя символьного массива и его размер. Если функция используется без аргументов, то произойдет считывание символа и удаление его из потока. Обычно функция get()
используется без аргументов, если необходимо удалить в очереди потока нулевой символ (программа 9.3. стр. 10 и 13).
Программа 9.3.
#include <iostream> using namespace std; int main() { const int buf = 80; char myStr1[buf]; char myStr2[buf]; cout << "Введите первую строку: "; cin.get(myStr1, buf); cin.get(); cout << "Введите вторую строку: "; cin.get(myStr2, buf); cin.get(); // В данной программе можно опустить cout << "Первая строка:\n" << myStr1 << endl; cout << "Вторая строка:\n" << myStr2 << endl; return 0; }
Введите первую строку: Это первая строка Введите вторую строку: Это вторая строка Первая строка: Это первая строка Вторая строка: Это вторая строка
2. Функция getline()
getline(str, buff, char_delim);
Функция имеет три аргумента. Два обязательных: имя массива и размер передаваемого массива с учетом символа конца строки. Третий аргумент (не обязательно) используется для указания завершающего символа. Если третьего аргумента нет, то предполагается, что завершающий символ — "\0"
. Функция считывает все символы (с учетом символа "\0"
) пока не встретит завершающий символ (или "\0"
, если завершающий символ не указан в качестве третьего аргумента). Функция считывает завершающий символ, но в символьный массив его не включает и в потоке ввода его не оставляет.
При выводе символьного массива не забывайте завершать его endl
или '\n'
.
При использовании оператора вставки "<<
" и имени массива он выводится одной строкой, так, как если бы мы использовали переменную строки.
Стандартная библиотека языка C++
предоставляет набор функций для работы со строками в стиле С
.
Заголовочный файл cctype
► isalnum
проверяет, является ли символ буквенно-цифровым
► isalpha
проверяет, является ли символ буквенным
► isdigit
проверяет, является ли символ цифрой
► isspace
проверяет, является ли символ символом пробела
► islower
проверяет, является ли символ символом в нижнем регистре
► isupper
проверяет, является ли символ символом прописной буквы
► ispunct
проверяет, является ли символ символом пунктуации
► tolower
преобразует символ в нижний регистр
► toupper
преобразует символ в верхний регистр
Все функции имеют следующий формат:
int имя_функции(int код_символа);
Следовательно, может потребоваться преобразования int → char
или наоборот, например:
s[i] = char(tolower(int(s[i])));
понизит регистр символов.
Пример. Дана строка подсчитать в ней количество букв, пробелов и цифровых символов.
Программа 9.4.
#include <iostream> #include <cctype> #include <cstring> using namespace std; int main() { int k = 0, l = 0, m = 0; const int buf = 80; char myStr[buf]; cout << "Введите строку:\n"; cin.getline(myStr, buf); for (auto i = 0; i < strlen(myStr); i++) { if (isalpha(myStr[i])) k++; if (isspace(myStr[i])) l++; if (isdigit(myStr[i])) m++; } cout << "Всего в строке:" << endl << "Букв - " << k << endl << "Пробелов - " << l << endl << "Цифр - " << m << endl; return 0; }
Введите строку: dddddddd 234 5 E ## %%ffff Всего в строке: Букв - 13 Пробелов - 5 Цифр - 4
Заголовочный файл cstdlib
► atof
преобразует строку в значение с плавающей точкой
► atoi
, atol
, atoll
преобразуют строку в целое число
► strtol
, strtoll
преобразуют строку в целое число
► strtoul
, strtoull
преобразуют строку в целое число без знака
► strtof
, strtod
, strtold
преобразуют строку в значение с плавающей точкой
Заголовочный файл cstring
► strcpy(dst, src)
копирует строку src
в строку dst
Пример. Скопировать в строку s1
начиная с пятой позиции, символы строки s2
начиная с третьей позиции (отсчет позиции с 0
)
Программа 9.5.
#include <iostream> #include <cstring> using namespace std; int main() { int buf = 80; char s1[buf]; char s2[buf]; cout << "Введите строку s1:" << endl; cin.getline(s1, buf); cout << "Введите строку s2:" << endl; cin.getline(s2, buf); strcpy(s1 + 5, s2 + 3); // равносильно strcpy(&s1[5], &s2[3]); cout << s1 << endl; return 0; }
Введите строку s1: 1234567890 Введите строку s2: 1234567890 123454567890
► strncpy(dst, src, len)
копирует len
символов строки (без учета нуля) src
в строку dst
; третий аргумент не обязательный.
► strcat(dst, src, len)
дописывает len
символов (без учета нуля) строки src
в конец dest
; третий аргумент не обязательный.
► strlen(str)
возвращает длину заданной строки (см. программу 9.4)
► strcmp
сравнивает две строки: возвращает 0
, если строки одинаковые, 1
, если первая строка больше, и -1
, если меньше
► strstr(dest, src)
находит первое вхождение подстроки src
в строке dest
.
Программа 9.6.
#include <iostream> #include <cstring> using namespace std; int main() { const int buf = 80; char myStr1[buf]; char myStr2[buf]; cout << "Введите строку:\n"; cin.getline(myStr1, buf); cout << "Введите подстроку для поиска:\n"; cin.getline(myStr2, buf); if (strstr(myStr1, myStr2)) cout << "Подстрока найдена!" << endl; else cout << "Подстрока не найдена!" << endl; return 0; }
Примечание. Функция strstr
возвращает, на самом деле, указатель на первый символ подстроки, найденной в dest
, или NULL
, если такой символ не найден. Таким образом, в программе 9.6 выражение условия (strstr(myStr1, myStr2)
) возвращающее указатель (не нулевое значение), будет расцениваться как true
.
Все функции можно посмотреть здесь
1. Какие выражения правильные, а какие нет?
'\n\n' "\n\n" cout << endl; cout << "\n"; cout << \n; cout << \n
2. Для чего используется символ '\0'?
3. В чем отличие функции getline от функции get?
1. Дан символ C. Вывести два символа, первый из которых предшествует символу C в кодовой таблице, а второй следует за символом C.
2. Дано целое число N (1 ≤ N ≤ 26). Вывести N первых прописных (то есть заглавных) букв латинского алфавита.