Символы

Иногда нам нужно хранить не целую строку, а один знак: цифру '7', знак '+', первую букву имени.

Для этого в Java есть тип char — отдельный символ.

char letter = 'A';
char digit  = '7';
char sign   = '+';

Основное

Символьная переменная объявляется так:

char c = 'A';

Примеры:

char letter = 'J';
char digit  = '3';
char space  = ' ';   // пробел

Важные моменты:

  • символ пишется в одинарных кавычках: 'A';
  • строка (String) — в двойных: "A", "Hello";
  • тип char хранит ровно один символ.

char и String: в чём разница

char — один символ.
String — последовательность символов (слово, фраза, текст).

char c = 'A';          // один символ
String s = "A";        // строка длины 1
String t = "Java";     // строка длины 4

Из строки можно взять символ по индексу:

String s = "Hello";

char first = s.charAt(0);   // 'H'
char second = s.charAt(1);  // 'e'

Чтение символа с клавиатуры

В Scanner нет метода nextChar(), поэтому обычно читают строку и берут первый символ.

import java.util.Scanner;

public class ReadCharExample {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        String s = in.next();     // читаем слово
        char c = s.charAt(0);     // берём первый символ

        System.out.println("Символ: " + c);
    }
}

Если нужно прочитать символ из целой строки:

String line = in.nextLine();   // читаем всю строку
char first = line.charAt(0);   // первый символ

Сравнение символов

Символы можно сравнивать так же, как числа: ==, !=, <, > и т.п.

char c = 'A';

boolean isA   = (c == 'A');
boolean isNot = (c != 'A');

Можно проверять, что символ — цифра или буква, с помощью класса Character:

char c = in.next().charAt(0);

boolean isDigit  = Character.isDigit(c);
boolean isLetter = Character.isLetter(c);
boolean isSpace  = Character.isWhitespace(c);

Код символа и простые шифры

Внутри компьютер хранит символ как число (код).
Можно преобразовать char в int:

char c = 'A';
int code = c;           // код символа
System.out.println(code);

Буквы латинского алфавита идут подряд по кодам.
Это позволяет делать простые сдвиги по алфавиту (идея шифра Цезаря):

char c = 'A';
char d = (char)(c + 1);   // 'B'

Важно: такие приёмы работают корректно для простых латинских букв без «дырок» в таблице. Для реальных систем шифрования используются другие методы, но для учебных задач этой идеи достаточно.


Типичные шаблоны

Определение типа символа

char c = in.next().charAt(0);

if (Character.isDigit(c)) {
    System.out.println("Цифра");
} else if (Character.isLetter(c)) {
    System.out.println("Буква");
} else {
    System.out.println("Другой символ");
}

Проверка, что символ — пробел

char c = in.next().charAt(0);

if (Character.isWhitespace(c)) {
    System.out.println("Пробельный символ");
}

Что нужно запомнить

Тип char хранит один символ и записывается в одинарных кавычках:

char c = 'A';

Чтобы прочитать символ через Scanner, обычно читают строку и берут charAt(0).

Символы можно сравнивать (==, !=) и при необходимости получать их числовой код, приводя к int.

Чтение и вывод символов, код символа

Для хранения символов в C++ используется тип char.

Пример чтения времени в формате hh:mm:

char c;
int h, m;
cin >> h >> c >> m;

В переменную c попадёт символ ':'.

Каждый символ кодируется числом (кодом). Вывод кода символа:

cout << (int)c;

Если есть целое число x с кодом символа, можно вывести сам символ:

cout << (char)x;

Коды первых 128 символов задаются таблицей ASCII. Ниже приведены основные символы:

32 (space)  48 0   64 @   80 P   96 `   112 p
33 !        49 1   65 A   81 Q   97 a   113 q
34 "        50 2   66 B   82 R   98 b   114 r
35 #        51 3   67 C   83 S   99 c   115 s
36 $        52 4   68 D   84 T   100 d  116 t
37 %        53 5   69 E   85 U   101 e  117 u
38 &        54 6   70 F   86 V   102 f  118 v
39 '        55 7   71 G   87 W   103 g  119 w
40 (        56 8   72 H   88 X   104 h  120 x
41 )        57 9   73 I   89 Y   105 i  121 y
42 *        58 :   74 J   90 Z   106 j  122 z
43 +        59 ;   75 K   91 [   107 k  123 {
44 ,        60 <   76 L   92 \   108 l  124 |
45 -        61 =   77 M   93 ]   109 m  125 }
46 .        62 >   78 N   94 ^   110 n  126 ~
47 /        63 ?   79 O   95 _   111 o  127 (del)

Коды от 0 до 31 — служебные символы.
Код 32 — пробел.
Коды 48..57 — цифры 0..9.
Коды 65..90 — заглавные латинские буквы.
Коды 97..122 — строчные латинские буквы.

Благодаря упорядоченности кодов можно делать вычисления по символам. Например, номер строчной буквы:

char c;
cin >> c;
cout << c - 'a' << endl;

Перевод строчной буквы в заглавную:

cout << (char)(c - 'a' + 'A') << endl;

Определение типа символа

Задача о надёжности пароля: дана строка, нужно проверить, что в ней есть хотя бы одна заглавная буква, хотя бы одна строчная буква и хотя бы одна цифра.

Решение через сравнение диапазонов:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string s;
    cin >> s;
    bool hasdigit = false, hasupper = false, haslower = false;
    for (int i = 0; i < s.length(); ++i){
        if (s[i] >= '0' && s[i] <= '9'){
            hasdigit = true;
        }
        if (s[i] >= 'a' && s[i] <= 'z'){
            haslower = true;
        }
        if (s[i] >= 'A' && s[i] <= 'Z'){
            hasupper = true;
        }
    }
    if (hasdigit && haslower && hasupper){
        cout << "YES";
    } else {
        cout << "NO";
    }
    return 0;
}

То же через функции из <cctype>:

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main()
{
    string s;
    cin >> s;
    bool hasdigit = false, hasupper = false, haslower = false;
    for (char c: s){
        if (isdigit(c)){
            hasdigit = true;
        }
        if (islower(c)){
            haslower = true;
        }
        if (isupper(c)){
            hasupper = true;
        }
    }
    if (hasdigit && haslower && hasupper){
        cout << "YES";
    } else {
        cout << "NO";
    }
    return 0;
}

По материалам:
М. Густокашин. Введение в программирование на языке C++. Сириус Курсы. Перейти к курсу.

В Python отдельного типа char нет. Один символ — это строка длины 1.

Основное

letter = 'A'
digit = '7'
sign = '+'

Один символ обычно пишут в одинарных кавычках: 'A' (можно и в двойных — это тоже строка).

Получить символ из строки

s = "Hello"
first = s[0]   # 'H'
second = s[1]  # 'e'

Чтение символа

s = input()   # читаем строку
c = s[0]      # берём первый символ

Проверки символа

c = '7'
is_digit = c.isdigit()
is_alpha = c.isalpha()
is_space = c.isspace()

Код символа и обратно

c = 'A'
code = ord(c)
print(code)

d = chr(code + 1)
print(d)

Java char хранит один элемент UTF-16 (16 бит). Обычно это один видимый символ, но некоторые символы (например, часть эмодзи) могут занимать два элемента.

C++ char — это 1 байт. Какой именно символ хранится в этом байте, зависит от кодировки. Для обычных латинских букв и цифр чаще всего всё ведёт себя ожидаемо.

Python Отдельного типа char нет: один символ — это строка (str) длины 1.

Сравнение В Java и C++ сравнивают char, в Python — строки длины 1. Сравнение идёт по коду символа.

Код символа Java: int code = c; C++: int code = (unsigned char)c; Python: ord(c)

Прочитать один символ Java: in.next().charAt(0) (читается слово, пробелы пропускаются) C++: std::cin >> c (пробелы пропускаются), для пробела — std::cin.get(c) Python: s = input(); c = s[0]