Стандартная библиотека С++ также предоставляет ряд встроенных функций для работы с символами. В основном они связанны с проверкой символов:
isupper(c): проверяет, является ли c заглавной буквой, по умолчанию от "A" до "Z"
islower(c): проверяет, является ли c буквой нижнего регистра, по умолчанию от 'a' до 'z'
isalpha(c): проверяет, является ли c алфавитным символом
isdigit(c): проверяет, является ли c цифрой от '0' до '9'
isxdigit(c): проверяет, является ли c шестнадцатеричной цифрой, от '0' до '9', от 'a' до 'f' или от 'A' до 'F'
isalnum(c): проверяет, является ли c алфавитно-цифровым символом; аналогично isisalpha(c) || isdigit(c)
isspace(c): проверяет, является ли c пробелом (' '), символом перевода строки ('\n'), возвратом каретки
('\r'), перевод страницы ('\f'), горизонтальная ('\t') или вертикальная ('\v') табуляция
isblank(c): проверяет, является ли c пробелом (' ') или символом табуляция ('\t')
ispunct(c): проверяет, является ли c символом пунктуации (один из следующих: _ { } [ ] # ( ) < > % : ; ? * + - / ^ & | ~ ! "=")
isprint(c): проверяет, является ли c печатным символом, который включает прописные или строчные буквы,цифры, знаки пунктуации и пробелы
iscntrl(c): проверяет, является ли c управляющим непечатным символом
isgraph(c): проверяет, имеет ли c графическое представление
tolower(c): переводит символ c в нижний регистр
toupper(c): переводит символ c в верхний регистр
Например, проверим, в каком регистре символ:
#include <iostream>
int main()
{
unsigned char letter {'a'};
if (std::isupper(letter))
std::cout << "Uppercase letter" << std::endl;
else if (std::islower(letter))
std::cout << "Lowercase letter" << std::endl;
else // если не буквенный символ
std::cout << "Undefined" << std::endl;
}
Данные функции очень часто применяются при обработке строк. Рассмотрим прстейшую задачу - нам надо извлечь из некоторого текста (например, из строки "Phone number: +1(234)456-78-90") номер телефона:
#include <iostream>
#include <string>
int main()
{
std::string text {"Phone number: +1(234)456-78-90"};
std::string phone; // строка для хранения номера
for(unsigned i{}; i < text.length(); i++)
{
// проверяем, является ли символ цифрой
if(std::isdigit(text[i]))
{
// добавляем в строку номера телефона
phone += text[i];
}
}
std::cout << phone << std::endl; // 12344567890
}
Здесь проходим по всем символам текста и, если символ представляет цифру, то заносим его в строку phone.
Другая задача - нам надо сравнить две строки вне зависимости от регистра. С одной стороны, мы могли бы использовать простую операцию сравнения ==, которая также может сравнивать строки. Но если мы попытаемся сравнить две строки, в которых хотя бы один символ отличается по регистру, то они будут не равны:
#include <iostream>
#include <string>
int main()
{
std::string word1 {"HELLO"};
word1 = "hello";
std::string word2 {"hello"};
if(word1 == word2)
{
std::cout << "strings are equal" << std::endl;
}
else
{
std::cout << "strings are not equal" << std::endl;
}
}
Результат данной программы:
strings are not equal
Чтобы организовать сравнение без учета регистра, мы могли бы переводить символы в верхний или нижний регистр и сравнивать их:
#include <iostream>
#include <string>
int main()
{
std::string word1 {"HELLO"};
std::string word2 {"hello"};
bool is_equal{true}; // равны ли строки
if(word1.length() != word2.length())
{
is_equal = false;
}
else
{
// сравниваем все символы
for(unsigned i{}; i < word1.length(); i++)
{
// переводим символы в нижний регистр и сравниваем
if(std::tolower(word1[i]) != std::tolower(word2[i]))
{
// если символы не равны, сбрасываем флаг равенства
is_equal = false;
break; // выходим из цикла
}
}
}
if(is_equal)
{
std::cout << word1 << " and " << word2 << " are equal" << std::endl;
}
else
{
std::cout << word1 << " and " << word2 << " are not equal" << std::endl;
}
}
В данном случае сначала сравниваем длину строк, так как если длины не равны, то сами строки тоже не равны.
Далее в цикле проходим по всем символам обоих строк, переводим их в нижний регистр и сравниваем. Если хотя бы одна пара соответствующих символов не равна, то сбрасываем флаг равенства is_equal в false и выходим из цикла, поскольку строки в этом случае будут уже не равны, и дальше нет смысла сравнивать символы.
Результат данной программы:
HELLO and hello are equal