§ 8. Символьные величины

Для хранения значения одного символа в языке С++ используется тип char. Величина данного типа занимает в памяти компьютера 1 байт. Значением величины может быть любой символ кодовой таблицы ASCII [1], которая приведена в приложении.

В таблице каждый символ имеет свой номер. Символы с номерами 0—32 являются служебными, и не все из них имеют визуальное отображение. Например, символ с номером 9 — символ, который соответствует нажатию клавиши Tab, символ с номером 13 соответствует нажатию клавиши Enter. Символ с номером 32 соответствует пробелу, он также не видим на экране.

Переменной типа char можно присвоить значение символа, при этом сам символ заключается в одинарные кавычки. Также переменной типа char можно присвоить числовое значение. Это значение — код символа в таблице. Если присвоить переменной типа int значение переменной типа char, то будет присвоен кодовый номер. Символы можно вводить и выводить так же, как числа (пример 8.1).

Символы можно сравнивать, при этом будут сравниваться их коды. Это означает, что больше тот символ, у которого код больше (пример 8.2).

При работе с консолью корректно обрабатываются только символы из первой части кодовой таблицы, т. е. символы с кодовыми номерами от 0 до 127. Во второй части кодовой таблицы находятся русские буквы, которые, как вы уже видели раньше, выводятся некорректно. Команда setlocale позволяет решить проблему с корректным выводом русских букв, но не с вводом.

Пример 8.3. Вывести на экран кодовую таблицу ASCII (начиная с символа с кодом 32).

Этапы выполнения задания

I. Результат не зависит от исходных данных.

II. Результат: таблица символов.

III. Алгоритм решения задачи.

1. В цикле от 32 до 255 перебираем значение кода символа. 
2. Выводим код символа и символ. Для вывода символа переменную типа int преобразуем в переменную типа char
3. Чтобы символы располагались друг под другом, задаем ширину области вывода.
4. Через каждые 8 символов переходим на новую строку.

IV. Используется локальная переменная i типа int в цикле и c — char.

Из результата работы программы примера 8.3 видно, что русские буквы все же присутствуют в кодовой таблице. Зная коды этих символов, можно организовать ввод и вывод русских букв, написав соответствующие функции преобразования. Однако это не очень удобно.

Для возможности ввода и вывода русских букв можно воспользоваться командами из библиотеки windows.h. Вводом символов управляет команда SetConsoleCP(1251), а команда SetConsoleOutputCP(1251) управляет выводом (пример 8.4). Эти команды позволяют использовать на консоли кодовую таблицу Windows 1251 (стандартная 8-битная кодировка для русскоязычных версий Microsoft Windows) вместо определенной по умолчанию таблицы ASCII. Таблица Windows 1251 используется и в редакторе кода системы программирования Code::Bloks (пример 8.5).

В C++ есть возможность выводить управляющие символы. Они начинаются с символа «\» (обратного слеша, бэкслеша), за которым следует определенная буква или цифра. Наиболее распространенные — '\n' (перевод строки) и '\t' (табуляция) (пример 8.6). Другие символы можно посмотреть в Приложение к главе 1.

И '\n', и endl оба переводят курсор на следующую строку. В чем между ними разница? При использовании cout данные для вывода могут помещаться в буфер данных [2], т. е. cout может не отправлять данные сразу же на вывод. Вместо этого он может оставить их при себе на некоторое время. Использование endl гарантирует, что все данные из буфера будут выведены, перед тем как продолжить. Использование endl может повлечь за собой снижение производительности, особенно если запись на устройство происходит медленно (например, запись данных в файл).


[1] ASCII — от англ. American Standard Code for Information Interchange. С кодовыми таблицами вы познакомитесь позднее.

[2] Буфер данных — специальная область памяти, используемая для ввода/вывода, в котором накапливаются данные до тех пор, пока не будет нажата клавиша  Enter или буфер не заполнится полностью. После этого накопленный блок данных становится доступным программе.

Тип данных char является знаковым типом и может хранить числовые значения от −128 до 127. Для работы с символами используют диапазон 0..127. Поскольку тип char хранит число, то к нему может быть применен модификатор unsigned. В этом случае диапазон числовых значений от 0 до 255.

Пример 8.1. Действия с символьными величинами.

#include <iostream>

 

using namespace std;

 

int main()

{

  char a, b, c;

  cout << "vvedi simvol" << endl;

  cin >> a;

  b = '#';

  c = 65;

  cout << "simvoly: " << endl;

  cout << a << ' ' << b << ' ' << c;

  int x = a, y = b, z = c;

  cout << endl << "cody: " << endl;

  cout << x << ' ' << y << ' ' << z;

  return 0;

}

Тестирование:

Пример 8.2. Сравнение символов.

#include <iostream>

 

using namespace std;

 

int main()

{

  char a, b;

  cout << "vvedi 2 simvola" << endl;

  cin >> a >> b;

  if (> b)

    cout << a << " > " << b << endl;

  else

    cout << a << " < " << b << endl;

  return 0;

}

Тестирование:

Пример 8.3.

V. Программа:

#include <iostream>

#include <iomanip>

 

using namespace std;

 

int main()

{

  for (int i = 32; i < 256; i++){

    char c = i;

    cout.width(5);

    cout << i << " " << c;

    if (% 8 == 7)

      cout << endl;

  }

  return 0;

}

 VI. Тестирование:

Пример 8.4. Вывод пяти русских букв, расположенных в таблице после введенной буквы.

Программа:

#include <iostream>

#include <windows.h>

 

using namespace std;

 

int main()

{

  SetConsoleCP(1251);

  SetConsoleOutputCP(1251);

  char c;

  cout << "буква" << endl;

  cin >> c;

  cout << "5 букв после" << endl;

  for (char i = c + 1; i < c + 6; i++)

    cout << i << ' ';

  return 0;

}

Тестирование:

Пример 8.5. Строка состояния.

Пример 8.6. Использование управляющих символов (на примере программы из примера 8.4).

Программа:

#include <iostream>

#include <windows.h>

 

using namespace std;

 

int main()

{

  SetConsoleCP(1251);

  SetConsoleOutputCP(1251);

  char c;

  cout << "буква" << '\n';

  cin >> c;

  cout << "5 букв после" << '\n';

  for (char i = c + 1; i < c + 6; i++)

    cout << i << '\t';

  cout << '\n';

  return 0;

}

Тестирование:

Обратите внимание, что в кодовой таблице ASCII между буквами «п» и «р» находятся символы псевдографики, которых нет в кодовой таблице Windows 1251.