Шаблонний клас std::ctype являється facet-аспектом локалі (похідний від класу locale::facet) і призначений для класифікування і перетворення символів, адаптуючи функціональність файлу ctype стандартної бібліотеки мови C до системи локалей C++. Оголошення класу приблизно виглядає наступним чином:
template <class charT> class ctype ;
Параметр шаблону charT вказує на тип комірок, які зберігають символи у певному кодування, з якими клас повинен мати справу. Клас std::ctype має захищений деструктор - програми повинні створювати примірники класів, які похідні від класу std::ctype, або використовувати примірники прив’язані до об’єктів локалі. Усі стандартні локалі повинні підтримувати наступну мінімальну кількість примірників даного класу:
  • ctype<char> - для звичайного типу символів;
  • ctype<wchar_t> - для розширеного типу символів.

Нутрощі класу

Вбудовані типи

ctype_base::mask
Тип успадкований від класу ctype_base. Використовується методами класу ctype в якості поверненого значення.

Константи

ctype_base::mask space ;
Константа позначає пропуски у тексті (пробіл, '\t', '\n').
ctype_base::mask print ;
Позначає символи, які можуть бути надрукованими.
ctype_base::mask cntrl ;
Константа позначає контролюючі символи.
ctype_base::mask upper ;
Константа позначає символи у верхньому регістрі.
ctype_base::mask lower ;
Позначає символи у нижньому регістрі.
ctype_base::mask alpha ;
Позначає символ, який представляє букву абетки.
ctype_base::mask digit ;
Константа позначає символ, який представляє букву.
ctype_base::mask punct ;
Позначає символи пунктуації.
ctype_base::mask xdigit ;
Константа позначає символи, які можуть представляти шістнадцяткові цифри.
ctype_base::mask alnum ;
Константа позначає буквенно-цифрові символи.
ctype_base::mask graph ;
Позначає символи, які мають графічне представлення.
locale::id id ;
Унікальний ідентифікатор facet-об’єкта.

Методи

// загальний конструктор
explicit ctype (size_t refs = 0) ;

// конструктор для ctype<char>
explicit ctype (const mask* tab = 0, 
                bool del = false, 
                size_t refs = 0) ;
Конструктори класу ctype. Параметр refs призначений для управління знищення об’єктів класу: для значення 0 (нуль) - об’єкт автоматично видаляється, коли видаляється останній об’єкт локалі, який містив даний facet-об’єкт; і значення 1 - коли об’єкт не повинен автоматично видалятися. Параметр tab призначений для вказування усіх класифікованих символамів кодування (на подобі поверненого методом ctype::is).
bool is (mask m, char_type c) const ;

const char_type* is (const char_type* low,
                     const char_type* high, 
                     mask* vec) 
      const ;
Класифікування символів. Варіант методу з двома параметрами призначений для тестування одного символу c на приналежність до будь-якого класу, вказаного у бітовій масці m. Варіант з трьома параметрами призначений для класифікування послідовності символів у проміжку [low, high), заповнюючи масив vec значеннями бітових констант. Даний метод являється делегатом - він викликає віртуальний захищений метод do_is, який реалізовують потомки даного класу.
char narrow (char_type c, char dfault) const ;

const char_type* narrow (const char_type* low, 
                         const char_type* high,
                         char dfault, 
                         char* to) const ;
Версія методу з двома параметрами, перетворює символ c (який найчастіше має тип wchar_t) у його відповідник типу char. Функція з чотирма параметрами виконує перетворення послідовності [low, high) і повертає масив перетворених значень; параметр to вказує на буфер типу char, який повинен вмістити усі перетворені символи з послідовності [low, high). Параметр dfault вказує на значення, яке функція повинна повертати, коли у розширеного символу немає відповідника у типі char. Даний метод являється делегатом - він викликає захищений метод do_narrow, який реалізовують потомки даного класу.
const char_type* scan_is (mask m, 
                          const char_type* low, 
                          const char_type* high) const ;
Даний метод повертає вказівник на перший елемент, який відповідає одному з константних бітових значень маски m, з проміжку [low, high). Даний метод являється делегатом - він викликає захищений віртуальний метод do_scan_is, який реалізовують потомки класу std::ctype.
const char_type* scan_not (mask m, 
                           const char_type* low, 
                           const char_type* high) const ;
Повертає вказівник на символ, який не належить жодній з категорії вказаній у параметрі m, з проміжку символів [low, high). Даний метод являється делегатом - він викликає метод do_scan_not, який реалізовують потомки класу std::ctype.
char_type tolower (char_type c) const ;

const char_type* tolower (char_type* low, 
                          const char_type* high) const ;
Версія методу з одним параметром перетворює вказаний символ c у нижній регістр і повертає його. Версія методу з двома параметрами перетворює усі символи з верхнього регістру у нижній з проміжку [low, high) і повертає high. Даний метод являється делегатом - він викликає віртуальний захищений метод do_tolower, який реалізовують потомки даного класу.
char_type toupper (char_type c) const ;

const char_type* toupper (char_type* low,
                          const char_type* high) const ;
Метод з одним параметром, перетворює символ c з верхнього регістру у нижній і повертає нове значення. Метод з двома параметрами перетворює усі символи проміжку [low, high) з верхнього регістру у нижній і повертає вказівник high. Даний метод являється делегатом - він викликає захищений віртуальний метод do_toupper, який реалізовують потомки даного класу.
char_type widen (char c) const ;

const char* widen (const char* low, 
                   const char* high, 
                   char_type* to) const ;
Метод з одним параметром, перетворює символ c з типу char у тип символів, який вказаний при створені примірника даного класу (параметр шаблону charT). Метод з трьома параметрами перетворює символи з послідовності [low, high) у пам’ять, на яку вказує to і повертає вказівник high.

Приклади

Приклад #1

Розглянемо простий приклад використання класу ctype, а точніше його метод is для одного символу.
#include <locale> /* все корисне включно з ctype */
#include <iostream> /* об'єкт cout */
using namespace std ; /* друкуємо усе без std */

/* головна фукнція програми */
int main (int argc, char** argv)
{
  /* створюємо піддослідну локаль
  ** пусте ім'я вказує на викристання 
  ** локалі, яку вказав користувач, наприклад
  ** через змінну середовища LANG */
  locale preferred ("") ;
  
  /* перевіряємо, чи існує у локалі об'єкт класу 
  ** ctype<wchar_t>, ми ж не бажаємо виключень в програмі */
  if (!has_facet < ctype<wchar_t> > (preferred))
  {
    /* якщо даний facet-об'єкт не присутній у локалі,
    ** виводимо відповідне повідомлення і завершуємо роботу
    ** програми
    ** Символи на кирилиці, можуть неправильно відображатись
    ** у терміналі. */
    cout << "Локаль немає facet-об'єкту ctype<wchar_t>." << endl ;
    
    return 0 ;
  }
  
  /* отримуємо facet-об'єкт класу ctype через функцію use_facet */
  const ctype<wchar_t>& lcfacet = use_facet < ctype<wchar_t> > (preferred) ;
  
  /* тестуємо різні символи і виводимо результат на екран*/
  cout << "Символ 'А', буква? - " 
        << lcfacet.is (lcfacet.alpha, L'А') << endl 
        
       << "Символ 'А', буква в верхньому регістрі? - " 
        << lcfacet.is (lcfacet.alpha | lcfacet.alpha,  L'А') << endl 
        
       << "Символ 'Ф', буква? - " 
        << lcfacet.is (lcfacet.alpha, L'Ф') << endl
        
       << "Символ 'F', буква в нижньому регістрі? - " 
        << lcfacet.is (lcfacet.lower, L'F') << endl 
        
       << "Символ '1', буква в верхньому регістрі? - " 
        << lcfacet.is (lcfacet.lower | lcfacet.alpha, L'1') << endl 
        
       << "Символ ';', символ пунктуації або пропуск? - " 
        << lcfacet.is (lcfacet.punct | lcfacet.space, L';') << endl ;
  
  return 0 ;
}
Вивід програми наступний: cpp_std_ctype_sample1-cxx

Приклад #2

Переглянемо приклад використання методу ctype::toupper.
#include <locale> /* все корисне включно з ctype */
#include <string.h>
#include <iostream> /* об'єкт cout */
using namespace std ; /* друкуємо усе без std */

/* головна фукнція програми */
int main (int argc, char** argv)
{
  /* створюємо піддослідну локаль
  ** пусте ім'я вказує на викристання 
  ** локалі, яку вказав користувач, наприклад
  ** через змінну середовища LANG */
  locale preferred ("") ;
  
  /* перевіряємо, чи існує у локалі об'єкти класів 
  ** ctype<wchar_t> і codecvt<wchar_t, char, mbstring_t>, 
  ** ми ж не бажаємо виключень в програмі */
  if (   !has_facet < ctype<wchar_t> > (preferred)
      || !has_facet < codecvt<wchar_t, char, mbstate_t> > (preferred))
  {
    /* якщо даний facet-об'єкт не присутній у локалі,
    ** виводимо відповідне повідомлення і завершуємо роботу
    ** програми
    ** Символи на кирилиці, можуть неправильно відображатись
    ** у терміналі. */
    cout << "Локаль немає потрібних facet-об'єктів." << endl ;
    
    return 0 ;
  }
  
  /* отримуємо facet-об'єкт класу ctype через функцію use_facet */
  const ctype<wchar_t>& lcfacet = use_facet < ctype<wchar_t> > (preferred) ;
  
  /* отримуємо facet-об'єкт класу codecvt через функцію use_facet,
  ** щоб вивести оригінальний рядок з перетвореним у термінал
  ** (термінал не вміє працювати з UTF-16 символами) */
  const codecvt<wchar_t,char,mbstate_t>& lcvtfacet 
          = use_facet < codecvt<wchar_t,char,mbstate_t> > (preferred) ;
  
  /* створюємо піддослідний рядок символів, елементи якого,
  ** будемо перетворювати у верхній регістр */
  wchar_t low_str[] = L"не той козак, що за водою пливе, а той, що проти." ;
  /* також визначаємо довжину рядка і створюємо відповідний вказівник */
  unsigned int lslen = sizeof(low_str)/sizeof(low_str[0]) ;
  const wchar_t* wptr = NULL ;
  
  /* творюємо буфери, куди будемо
  ** запиувати перетворені у UTF-8 символи 
  ** з константою довжини і вказівником на елемент типу */
  const unsigned int deflen = 256 ;
  char byte_low_str [deflen] ;
  char byte_converted_str [deflen] ;
  char* bptr = NULL ;
  
  /* створюємо стан перетворення */
  mbstate_t state ;
  
  /* встановлюємо стан перетворення в початкове значення*/
  memset (&state, 0, sizeof(state)) ;
  /* виконуємо перетворення символів нижнього решістру
  ** з UTF-16 у UTF-8 у буфер byte_low_str */
  lcvtfacet.out (state, low_str, low_str+lslen, wptr,
                 byte_low_str, byte_low_str+deflen, bptr) ;
                 
  /* перетворюємо симоли нижнього регістру у верхній */
  lcfacet.toupper (low_str, low_str+lslen) ;
  /* тепер рядок low_str містить усі символи у верхньому регістрі */
  
  /* встановлюємо стан перетворення в початкове значення*/
  memset (&state, 0, sizeof(state)) ;
  /* виконуємо перетворення символів верхнього регістру
  ** з розширеного UTF-16 у байтовий UTF-8 буферу byte_converted_str */
  lcvtfacet.out (state, low_str, low_str+lslen, wptr,
                 byte_converted_str, byte_converted_str+deflen, bptr) ;
  
  /* повідомлення на UTF-8 кирилиці
  ** може некоректно відображатись у терміналі */
  cout << "Оригінал   : " << byte_low_str << endl
       << "У верхньому: " << byte_converted_str << endl ;
  
  return 0 ;
}
Вивід програми наступний: cpp_std_ctype_sample2-cxx_with_std_codecvt
Категорії: