Как работать с char в c
Перейти к содержимому

Как работать с char в c

  • автор:

char (Справочник по C#)

Ключевое слово типа char — это псевдоним для типа структуры System.Char .NET, представляющий символ UTF-16 в Юникоде.

Type Диапазон Размер Тип .NET
char От U+0000 до U+FFFF 16 разрядов System.Char

Значение по умолчанию для типа char — \0 , то есть U+0000.

Тип char поддерживает сравнение, проверку равенства, а также операции инкремента и декремента. Кроме того, для операндов char арифметические и побитовые логические операторы выполняют операцию с соответствующими кодами символов и создают результат типа int .

Тип string представляет текст как последовательность значений char .

Литералы

Значение char можно указать следующим образом:

  • символьный литерал;
  • escape-последовательность Юникода, то есть символы \u , за которыми следует шестнадцатеричное представление кода символа из четырех символов;
  • шестнадцатеричная escape-последовательность, то есть символы \x , за которыми следует шестнадцатеричное представление кода символа.
var chars = new[] < 'j', '\u006A', '\x006A', (char)106, >; Console.WriteLine(string.Join(" ", chars)); // output: j j j j 

Как показано в предыдущем примере, можно также привести значение кода символа к соответствующему значению char .

В случае escape-последовательности Юникода необходимо указать все четыре шестнадцатеричные цифры. То есть \u006A — допустимая escape-последовательность, а \u06A и \u6A нет.

В случае шестнадцатеричной escape-последовательности начальные нули можно опустить. То есть \x006A , \x06A и \x6A — допустимые escape-последовательности, соответствующие одному символу.

Преобразования

Тип char неявно преобразуется в следующие целочисленные типы: ushort , int , uint , long и ulong . Он также может быть неявно преобразован во встроенные числовые типы с плавающей запятой: float , double и decimal . Он явно преобразуется в целочисленные типы sbyte , byte и short .

Неявные преобразования из других типов в тип char не предусмотрены. Но любой целочисленный тип или числовой тип с плавающей запятой явно преобразуется в char .

Спецификация языка C#

Дополнительные сведения см. в разделе Целочисленные типы в статье Спецификации языка C#.

См. также

  • справочник по C#
  • Типы значений
  • Строки
  • System.Text.Rune
  • Кодировка символов в .NET

Совместная работа с нами на GitHub

Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.

Строки в си. Введение

Э то вводная статья по строкам в си. Более подробное описание и примеры будут, когда мы научимся работать с памятью и указателями. В компьютере все значения хранятся в виде чисел. И строки тоже, там нет никаких символов и букв. Срока представляет собой массив чисел. Каждое число соответствует определённому символу, который берётся из таблицы кодировки. При выводе на экран символ отображается определённым образом.
Для хранения строк используются массивы типа char. Ещё раз повторюсь – тип char – числовой, он хранит один байт данных. Но в соответствии с таблицей кодировки каждое из этих чисел связано с символом. И в обратную сторону – каждый символ определяется своим порядковым номером в таблице кодировки. Например

#include #include void main()

Мы создали две переменные, одна типа char, другая int. Литера ‘A’ имеет числовое значение 65. Это именно литера, а не строка, поэтому окружена одинарными кавычками. Мы можем вывести её на печать как букву

printf("display as char %c\n", c);

Тогда будет выведено
A Если вывести её как число, то будет 65 Точно также можно поступить и с числом 65, которое хранится в переменной типа int.
Спецсимволы также имеют свой номер

#include #include void main()

Здесь будет сначала «выведен» звуковой сигнал, затем его числовое значение, затем опять звуковой сигнал. Строка в си – это массив типа char, последний элемент которого хранит терминальный символ ‘\0’. Числовое значение этого символа 0, поэтому можно говорить, что массив оканчивается нулём.
Например

#include #include void main() < char word[10]; word[0] = 'A'; word[1] = 'B'; word[2] = 'C'; word[3] = '\0'; //word[3] = 0; эквивалентно printf("%s", word); getch(); >

Для вывода использовался ключ %s. При этом строка выводится до первого терминального символа, потому что функция printf не знает размер массива word.
Если в этом примере не поставить

word[3] = '\0';

то будет выведена строка символов произвольной длины, до тех пор, пока не встретится первый байт, заполненный нулями.

#include #include void main() < char word[10] = "ABC"; char text[100] = ; printf("%s\n", word); printf("%s", text); getch(); >

В данном случае всё корректно. Строка «ABC» заканчивается нулём, и ею мы инициализируем массив word. Строка text инициализируется побуквенно, все оставшиеся символы, как следует из главы про массивы, заполняются нулями.

Чтение строк

Д ля того, чтобы запросить у пользователя строку, необходимо создать буфер. Размер буфера должен быть выбран заранее, так, чтобы введённое слово в нём поместилось. При считывании строк есть опасность того, что пользователь введёт данных больше, чем позволяет буфер. Эти данные будут считаны и помещены в память, и затрут собой чужие значения. Таким образом можно провести атаку, записав нужные байты, в которых, к примеру, стоит переход на участок кода с вредоносной программой, или логгирование данных.

#include #include void main()

В данном случае количество введённых символов ограничено 19, а размер буфера на 1 больше, так как необходимо хранить терминальный символ. Напишем простую программу, которая запрашивает у пользователя строку и возвращает её длину.

#include #include void main() < char buffer[128]; unsigned len = 0; scanf("%127s", buffer); while (buffer[len] != '\0') < len++; >printf("length(%s) == %d", buffer, len); getch(); >

Так как числовое значение символа ‘\0’ равно нулю, то можно записать

while (buffer[len] != 0)
while (buffer[len])

Теперь напишем программу, которая запрашивает у пользователя два слова и сравнивает их

#include #include /* Результатом сравнения будет число 0 если слова равны 1 если первое слово больше второго в лексикографическом порядке -1 если второе слово больше */ void main() < char firstWord[128]; //Первое слово char secondWord[128]; //Второе слово unsigned i; //Счётчик int cmpResult = 0; //Результат сравнения scanf("%127s", firstWord); scanf("%127s", secondWord); for (i = 0; i < 128; i++) < if (firstWord[i] >secondWord[i]) < //Больше даже если второе слово уже закончилось, потому что //тогда оно заканчивается нулём cmpResult = 1; break; >else if (firstWord[i] < secondWord[i]) < cmpResult = -1; break; >> printf("%d", cmpResult); getch(); >

Так как каждая буква имеет числовое значение, то их можно сравнивать между собой как числа. Кроме того, обычно (но не всегда!) буквы в таблицах кодировок расположены по алфавиту. Поэтому сортировка по числовому значению также будет и сортировкой по алфавиту.

ru-Cyrl 18- tutorial Sypachev S.S. 1989-04-14 sypachev_s_s@mail.ru Stepan Sypachev students

email

Всё ещё не понятно? – пиши вопросы на ящик

C++: Тип сhar

В этом уроке мы рассмотрим последний целочисленный тип: char .

сhar предназначен для хранения символов, таких как буквы и цифры. Но почему же char это целочисленный тип? Все дело в том, что хранение чисел в памяти компьютера не представляет сложности, тогда как хранение букв связанно с рядом проблем. Поэтому в языках программирования принят простой подход: хранить символы в памяти компьютеров в виде числовых кодов.

Таким образом тип char является еще одним целочисленным типом.

int main() < char symbol < 'M' >; int number < symbol >; std::cout M std::cout 77 return 0; > 

Интересный момент состоит в том, что на самом деле и в переменной number и в переменной symbol хранится значение 77, а когда дело доходит до вывода объект cout по-разному интерпретирует эти переменные.

char по умолчанию может быть как беззнаковым так и знаковым типом. Тут все зависит от компилятора. Если для нас крайне важно, что бы тип char обладал определенным поведением, надо указать это явно:

unsigned char symbol // беззнаковый, диапазон от 0 до 255 signed char symbol // знаковый, диапазон от -128 до 127 

Под переменную типа char выделяется один байт, для работы с символами в кодировке ASCII этого вполне достаточно, но для работы с Unicode нет. Если мы попытаемся определить переменную типа char , получим ошибку переполнения:

int main()
main.cpp:2:21: error: narrowing conversion of '53412' from 'int' to 'char' [-Wnarrowing] 2 | char symbol = 'Ф'; | ^~~

Для работы с символами которые превышают один байт, есть расширенный тип wchar_t — под котрый выделяется два байта памяти, а начиная со стандарта С++ 11 char16_t и char32_t :

int main()

Что бы указать принадлежность к тому или иному символьному типу, перед символом ставится префикс. Например, префикс L обозначает расширенный строковый литерал.

Задание

Определите внутри функции main() переменную типа char и сохраните в нее символ U . Выведите значение переменный в консоль.

Упражнение не проходит проверку — что делать? ��

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.

В моей среде код работает, а здесь нет ��

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя ��

Это нормально ��, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно ��

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.

Урок №35. Символьный тип данных char

Хоть тип char и относится к целочисленным типам данных (и, таким образом, следует всем их правилам), работа с char несколько отличается от работы с обычными целочисленными типами.

Оглавление:

  1. Тип данных char
  2. Вывод символов
  3. Оператор static_cast
  4. Ввод символов
  5. Размер, диапазон и знак типа сhar
  6. Управляющие символы
  7. Что использовать: ‘\n’ или std::endl?
  8. Другие символьные типы: wchar_t, char16_t и char32_t
  9. В чём разница между одинарными и двойными кавычками при использовании с символами?

Тип данных char

Переменная типа char занимает 1 байт. Однако вместо конвертации значения типа char в целое число, оно интерпретируется как ASCII-символ.

ASCII (сокр. от «American Standard Code for Information Interchange») — это американский стандартный код для обмена информацией, который определяет способ представления символов английского языка (+ несколько других) в виде чисел от 0 до 127. Например: код буквы ‘а’ — 97, код буквы ‘b’ — 98. Символы всегда помещаются в одинарные кавычки.

Таблица ASCII-символов:

Код Символ Код Символ Код Символ Код Символ
0 NUL (null) 32 (space) 64 @ 96 `
1 SOH (start of header) 33 ! 65 A 97 a
2 STX (start of text) 34 66 B 98 b
3 ETX (end of text) 35 # 67 C 99 c
4 EOT (end of transmission) 36 $ 68 D 100 d
5 ENQ (enquiry) 37 % 69 E 101 e
6 ACK (acknowledge) 38 & 70 F 102 f
7 BEL (bell) 39 71 G 103 g
8 BS (backspace) 40 ( 72 H 104 h
9 HT (horizontal tab) 41 ) 73 I 105 i
10 LF (line feed/new line) 42 * 74 J 106 j
11 VT (vertical tab) 43 + 75 K 107 k
12 FF (form feed / new page) 44 , 76 L 108 l
13 CR (carriage return) 45 77 M 109 m
14 SO (shift out) 46 . 78 N 110 n
15 SI (shift in) 47 / 79 O 111 o
16 DLE (data link escape) 48 0 80 P 112 p
17 DC1 (data control 1) 49 1 81 Q 113 q
18 DC2 (data control 2) 50 2 82 R 114 r
19 DC3 (data control 3) 51 3 83 S 115 s
20 DC4 (data control 4) 52 4 84 T 116 t
21 NAK (negative acknowledge) 53 5 85 U 117 u
22 SYN (synchronous idle) 54 6 86 V 118 v
23 ETB (end of transmission block) 55 7 87 W 119 w
24 CAN (cancel) 56 8 88 X 120 x
25 EM (end of medium) 57 9 89 Y 121 y
26 SUB (substitute) 58 : 90 Z 122 z
27 ESC (escape) 59 ; 91 [ 123
28 FS (file separator) 60 92 \ 124 |
29 GS (group separator) 61 = 93 ] 125 >
30 RS (record separator) 62 > 94 ^ 126 ~
31 US (unit separator) 63 ? 95 _ 127 DEL (delete)

Символы от 0 до 31 в основном используются для форматирования вывода. Большинство из них уже устарели.

Символы от 32 до 127 используются для вывода. Это буквы, цифры, знаки препинания, которые большинство компьютеров использует для отображения текста (на английском языке).

Следующие два стейтмента выполняют одно и то же (присваивают переменным типа char целое число 97 ):

char ch1 ( 97 ) ; // инициализация переменной типа char целым числом 97
char ch2 ( ‘a’ ) ; // инициализация переменной типа char символом ‘a’ (97)

Будьте внимательны при использовании фактических чисел с числами, которые используются для представления символов (из ASCII-таблицы). Следующие два стейтмента выполняют не одно и то же:

char ch ( 5 ) ; // инициализация переменной типа char целым числом 5
char ch ( ‘5’ ) ; // инициализация переменной типа char символом ‘5’ (53)

Вывод символов

При выводе переменных типа char, объект cout выводит символы вместо цифр:

char ch ( 97 ) ; // несмотря на то, что мы инициализируем переменную ch целым числом
std :: cout << ch << std :: endl ; // cout выводит символ

Также вы можете выводить литералы типа char напрямую:

std :: cout << 'b' << std :: endl ;

Оператор static_cast

Если вы хотите вывести символы в виде цифр, а не в виде букв, то вам нужно сообщить cout выводить переменные типа char в виде целочисленных значений. Не очень хороший способ это сделать — присвоить переменной типа int переменную типа char и вывести её:

char ch ( 97 ) ;
int i ( ch ) ; // присваиваем значение переменной ch переменной типа int
std :: cout << i << std :: endl ; // выводим значение переменной типа int

Лучшим способом является конвертация переменной из одного типа данных в другой с помощью оператора static_cast.

Синтаксис static_cast выглядит следующим образом:

Оператор static_cast принимает значение из (выражения) в качестве входных данных и конвертирует его в указанный вами .

Пример использования оператора static_cast для конвертации типа char в тип int:

char ch ( 97 ) ;
std :: cout << ch << std :: endl ; std :: cout << static_cast < int >( ch ) << std :: endl ;
std :: cout << ch << std :: endl ;

Результат выполнения программы:

Запомните, static_cast принимает (выражение) в качестве входных данных. Если мы используем переменную в (выражении) , то эта переменная изменяет свой тип только в стейтменте с оператором static_cast. Процесс конвертации никак не влияет на исходную переменную с её значением! В вышеприведенном примере, переменная ch остается переменной типа char с прежним значением, чему является подтверждением последний стейтмент с cout.

Также в static_cast нет никакой проверки по диапазону, так что если вы попытаетесь использовать числа, которые будут слишком большие или слишком маленькие для конвертируемого типа, то произойдет переполнение.

Более подробно о static_cast мы еще поговорим на соответствующем уроке.

Ввод символов

Следующая программа просит пользователя ввести символ. Затем она выводит этот символ и его ASCII-код:

std :: cout << "Input a keyboard character: " ; std :: cin >> ch ;
std :: cout << ch << " has ASCII code " << static_cast < int >( ch ) << std :: endl ;

Результат выполнения программы:

Input a keyboard character: q
q has ASCII code 113

Обратите внимание, даже если cin позволит вам ввести несколько символов, переменная ch будет хранить только первый символ (именно он и помещается в переменную). Остальная часть пользовательского ввода останется во входном буфере, который использует cin, и будет доступна для использования последующим вызовам cin.

Рассмотрим это всё на практике:

std :: cout << "Input a keyboard character: " ; // предположим, что пользователь ввел abcd std :: cin >> ch ; // ch = ‘a’, «bcd» останется во входном буфере
std :: cout << ch << " has ASCII code " << static_cast < int >( ch ) << std :: endl ;

// Обратите внимание, следующий cin не просит пользователя что-либо ввести, данные берутся из входного буфера!

std :: cin >> ch ; // ch = ‘b’, «cd» останется в буфере
std :: cout << ch << " has ASCII code " << static_cast < int >( ch ) << std :: endl ;

Результат выполнения программы:

Input a keyboard character: abcd
a has ASCII code 97
b has ASCII code 98

Размер, диапазон и знак типа сhar

В языке С++ для переменных типа char всегда выделяется 1 байт. По умолчанию, char может быть как signed, так и unsigned (хотя обычно signed). Если вы используете char для хранения ASCII-символов, то вам не нужно указывать знак переменной (поскольку signed и unsigned могут содержать значения от 0 до 127).

Но если вы используете тип char для хранения небольших целых чисел, то тогда следует уточнить знак. Переменная типа char signed может хранить числа от -128 до 127. Переменная типа char unsigned имеет диапазон от 0 до 255.

Управляющие символы

В языке C++ есть управляющие символы (или «escape-последовательности»). Они начинаются с бэкслеша ( \ ), а затем следует определенная буква или цифра.

Наиболее распространенным управляющим символов в языке С++ является \n , который обозначает символ новой строки:

std :: cout << "First line\nSecond line" << std :: endl ;

First line
Second line

Еще одним часто используемым управляющим символом является \t , который заменяет клавишу TAB, вставляя большой отступ:

std :: cout << "First part\tSecond part" ;

First part Second part

Таблица всех управляющих символов в языке C++:

Название Символ Значение
Предупреждение (alert) \a Предупреждение (звуковой сигнал)
Backspace \b Перемещение курсора на одну позицию назад
formfeed \f Перемещение курсора к следующей логической странице
Символ новой строки (newline) \n Перемещение курсора на следующую строку
Возврат каретки (carriage return) \r Перемещение курсора в начало строки
Горизонтальный таб (horizontal tab) \t Вставка горизонтального TAB
Вертикальный таб (vertical tab) \v Вставка вертикального TAB
Одинарная кавычка \’ Вставка одинарной кавычки (или апострофа)
Двойная кавычка \” Вставка двойной кавычки
Бэкслеш \\ Вставка обратной косой черты (бэкслеша)
Вопросительный знак \? Вставка знака вопроса
Восьмеричное число \(number) Перевод числа из восьмеричной системы счисления в тип char
Шестнадцатеричное число \x(number) Перевод числа из шестнадцатеричной системы счисления в тип char

Рассмотрим пример в коде:

std :: cout << "\"This is quoted text\"\n" ; std :: cout << "This string contains a single backslash \\" << std :: endl ; std :: cout << "6F in hex is char \'\x6F\'" << std :: endl ;

Результат выполнения программы:

«This is quoted text»
This string contains a single backslash \
6F in hex is char ‘o’

Что использовать: ‘\n’ или std::endl?

Вы могли заметить, что в последнем примере мы использовали \n для перемещения курсора на следующую строку. Но мы могли бы использовать и std::endl . Какая между ними разница? Сейчас разберемся.

При использовании std::cout, данные для вывода могут помещаться в буфер, т.е. std::cout может не отправлять данные сразу же на вывод. Вместо этого он может оставить их при себе на некоторое время (в целях улучшения производительности).

И \n , и std::endl оба переводят курсор на следующую строку. Только std::endl еще гарантирует, что все данные из буфера будут выведены, перед тем, как продолжить.

Так когда же использовать \n , а когда std::endl ?

Используйте std::endl , когда нужно, чтобы ваши данные выводились сразу же (например, при записи в файл или при обновлении индикатора состояния какого-либо процесса). Обратите внимание, это может повлечь за собой незначительное снижение производительности, особенно если запись на устройство происходит медленно (например, запись файла на диск).

Используйте \n во всех остальных случаях.

Другие символьные типы: wchar_t, char16_t и char32_t

Тип wchar_t следует избегать практически во всех случаях (кроме тех, когда происходит взаимодействие с Windows API).

Так же, как и стандарт ASCII использует целые числа для представления символов английского языка, так и другие кодировки используют целые числа для представления символов других языков. Наиболее известный стандарт (после ASCII) — Unicode, который имеет в запасе более 110 000 целых чисел для представления символов из разных языков.

Существуют следующие кодировки Unicode:

UTF-32 — требует 32 бита для представления символа.

UTF-16 — требует 16 бит для представления символа.

UTF-8 — требует 8 бит для представления символа.

Типы char16_t и char32_t были добавлены в C++11 для поддержки 16-битных и 32-битных символов Unicode (8-битные символы и так поддерживаются типом char).

В чём разница между одинарными и двойными кавычками при использовании с символами?

Как вы уже знаете, символы всегда помещаются в одинарные кавычки (например, ‘а’ , ‘+’ , ‘5’ ). Переменная типа char представляет только один символ (например, буква а , символ + , число 5 ). Следующий стейтмент не является корректным:

char ch ( ’56’ ) ; // переменная типа char может хранить только один символ

Текст, который находится в двойных кавычках, называется строкой (например, «Hello, world!» ). Строка (тип string) — это набор последовательных символов.

Вы можете использовать литералы типа string в коде:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *