Кодирование символов
Кодировка символов (часто называемая также кодовой страницей ) – это набор числовых значений, которые ставятся в соответствие группе алфавитно-цифровых символов, знаков пунктуации и специальных символов.
Для кодировки символов в Windows используется таблица ASCII (American Standard Code for Interchange of Information).
В ASCII первые 128 символов всех кодовых страниц состоят из базовой таблицы символов. Первые 32 кода базовой таблицы, начиная с нулевого, размещают управляющие коды.
Символ | Код | Клавиши | Значение |
nul | 0 | Ctrl + @ | Нуль |
soh | 1 | Ctrl + A | Начало заголовка |
stx | 2 | Ctrl + B | Начало текста |
etx | 3 | Ctrl + C | Конец текста |
eot | 4 | Ctrl + D | Конец передачи |
enq | 5 | Ctrl + E | Запрос |
ack | 6 | Ctrl + F | Подтверждение |
bel | 7 | Ctrl + G | Сигнал (звонок) |
bs | 8 | Ctrl + H | Забой (шаг назад) |
ht | 9 | Ctrl + I | Горизонтальная табуляция |
lf | 10 | Ctrl + J | Перевод строки |
vt | 11 | Ctrl + K | Вертикальная табуляция |
ff | 12 | Ctrl + L | Новая страница |
cr | 13 | Ctrl + M | Возврат каретки |
so | 14 | Ctrl + N | Выключить сдвиг |
si | 15 | Ctrl + O | Включить сдвиг |
dle | 16 | Ctrl + P | Ключ связи данных |
dc1 | 17 | Ctrl + Q | Управление устройством 1 |
dc2 | 18 | Ctrl + R | Управление устройством 2 |
dc3 | 19 | Ctrl + S | Управление устройством 3 |
dc4 | 20 | Ctrl + T | Управление устройством 4 |
nak | 21 | Ctrl + U | Отрицательное подтверждение |
syn | 22 | Ctrl + V | Синхронизация |
etb | 23 | Ctrl + W | Конец передаваемого блока |
can | 24 | Ctrl + X | Отказ |
em | 25 | Ctrl + Y | Конец среды |
sub | 26 | Ctrl + Z | Замена |
esc | 27 | Ctrl + [ | Ключ |
fs | 28 | Ctrl + \ | Разделитель файлов |
gs | 29 | Ctrl + ] | Разделитель группы |
rs | 30 | Ctrl + ^ | Разделитель записей |
us | 31 | Ctrl + _ | Разделитель модулей |
Базовая таблица кодировки ASCII
Символы с номерами от 128 до 255 представляют собой таблицу расширения и варьируются в зависимости от набора скриптов, представленных кодировкой символов. Набор символов таблицы расширения различается в зависимости от выбранной кодовой страницы:
1251 – кодовая страница Windows
128 Ђ | 144 Ђ | 160 | 176 ° | 192 А | 208 Р | 224 а | 240 р |
129 Ѓ | 145 ‘ | 161 Ў | 177 ± | 193 Б | 209 С | 225 б | 241 с |
130 ‚ | 146 ’ | 162 ў | 178 I | 194 В | 210 Т | 226 в | 242 т |
131 ѓ | 147 “ | 163 J | 179 i | 195 Г | 211 У | 227 г | 243 у |
132 „ | 148 ” | 164 ¤ | 180 ґ | 196 Д | 212 Ф | 228 д | 244 ф |
133 … | 149 • | 165 Ґ | 181 μ | 197 Е | 213 Х | 229 е | 245 х |
134 † | 150 – | 166 ¦ | 182 ¶ | 198 Ж | 214 Ц | 230 ж | 246 ц |
135 ‡ | 151 — | 167 § | 183 · | 199 З | 215 Ч | 231 з | 247 ч |
136 € | 152 □ | 168 Ё | 184 ё | 200 И | 216 Ш | 232 и | 248 ш |
137 ‰ | 153 ™ | 169 © | 185 № | 201 Й | 217 Щ | 233 й | 249 щ |
138 Љ | 154 љ | 170 Є | 186 є | 202 К | 218 Ъ | 234 к | 250 ъ |
139 | 171 « | 187 » | 203 Л | 219 Ы | 235 л | 251 ы | |
140 Њ | 156 њ | 172 ¬ | 188 j | 204 М | 220 Ь | 236 м | 252 ь |
141 Ќ | 157 ќ | 173 | 189 S | 205 Н | 221 Э | 237 н | 253 э |
142 Ћ | 158 ћ | 174 ® | 190 s | 206 О | 222 Ю | 238 о | 254 ю |
143 Џ | 159 џ | 175 Ï | 191 ї | 207 П | 223 Я | 239 п | 255 я |
866 – кодовая страница DOS
128 А | 144 Р | 160 а | 176 ░ | 192 └ | 208 ╨ | 224 р | 240 ≡Ё |
129 Б | 145 С | 161 б | 177 ▒ | 193 ┴ | 209 ╤ | 225 с | 241 ±ё |
130 В | 146 Т | 162 в | 178 ▓ | 194 ┬ | 210 ╥ | 226 т | 242 ≥ |
131 Г | 147 У | 163 г | 179 │ | 195 ├ | 211 ╙ | 227 у | 243 ≤ |
132 Д | 148 Ф | 164 д | 180 ┤ | 196 ─ | 212 ╘ | 228 ф | 244 ⌠ |
133 Е | 149 Х | 165 е | 181 ╡ | 197 ┼ | 213 ╒ | 229 х | 245 ⌡ |
134 Ж | 150 Ц | 166 ж | 182 ╢ | 198 ╞ | 214 ╓ | 230 ц | 246 ¸ |
135 З | 151 Ч | 167 з | 183 ╖ | 199 ╟ | 215 ╫ | 231 ч | 247 » |
136 И | 152 Ш | 168 и | 184 ╕ | 200 ╚ | 216 ╪ | 232 ш | 248 ° |
137 Й | 153 Щ | 169 й | 185 ╣ | 201 ╔ | 217 ┘ | 233 щ | 249 · |
138 К | 154 Ъ | 170 к | 186 ║ | 202 ╩ | 218 ┌ | 234 ъ | 250 ∙ |
139 Л | 155 Ы | 171 л | 187 ╗ | 203 ╦ | 219 █ | 235 ы | 251 √ |
140 М | 156 Ь | 172 м | 188 ╝ | 204 ╠ | 220 ▄ | 236 ь | 252 ⁿ |
141 Н | 157 Э | 173 н | 189 ╜ | 205 ═ | 221 ▌ | 237 э | 253 ² |
142 О | 158 Ю | 174 о | 190 ╛ | 206 ╬ | 222 ▐ | 238 ю | 254 ■ |
143 П | 159 Я | 175 п | 191 ┐ | 207 ╧ | 223 ▀ | 239 я | 255 |
Русские названия основных спецсимволов:
Символ | Название |
` | гравис, кавычка, обратный машинописный апостроф |
` | гравис, кавычка, обратный машинописный апостроф |
тильда | |
! | восклицательный знак |
@ | эт, коммерческое эт, «собака» |
# | октоторп, решетка, диез |
$ | знак доллара |
% | процент |
^ | циркумфлекс, знак вставки |
& | амперсанд |
* | астериск, звездочка, знак умножения |
( | левая открывающая круглая скобка |
) | правая закрывающая круглая скобка |
— | минус, дефис |
_ | знак подчеркивания |
= | знак равенства |
+ | плюс |
[ | левая открывающая квадратная скобка |
] | правая закрывающая квадратная скобка |
< | левая открывающая фигурная скобка |
> | правая закрывающая фигурная скобка |
; | точка с запятой |
: | двоеточие |
‘ | машинописный апостроф, одинарная кавычка |
« | двойная кавычка |
, | запятая |
. | точка |
/ | слэш, косая черта, знак дроби |
правая закрытая угловая скобка, знак больше | |
\ | обратный слэш, обратная косая черта |
| | вертикальная черта |
Кодировка UNICODE
Юникод (Unicode) — стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. Стандарт предложен в 1991 году некоммерческой организацией «Консорциум Юникода».
В Unicode используются 16-битовые (2-байтовые) коды, что позволяет представить 65536 символов.
Применение стандарта Unicode позволяет закодировать очень большое число символов из разных письменностей: в документах Unicode могут соседствовать китайские иероглифы, математические символы, буквы греческого алфавита, латиницы и кириллицы, при этом становится ненужным переключение кодовых страниц.
Тип кодировки задается в свойствах проекта Microsoft Visual Studio:
Многобайтовая кодировка предполагает использование кодировки ASCII.
При этом при построении проекта используется директива условной компиляции, переопределяющая тип TCHAR :
Для перекодирования строки в формат Unicode без изменения кодировки файла используется макроопределение
_T(«строка»)
Си. Представление символов
Зачем нужны кодировки символов?
Символы на экране компьютера формируются на основе наборов векторных (редко матричных) представлений всевозможных символов. Они находятся в файлах со шрифтами, которые установлены на компьютере. Выбор конкретного представления осуществляется по коду, который позволяет взять из этого набора представлений именно тот символ, который нужно будет вставить в нужное место.
Понятно, что за сами формы символов отвечают шрифты, а вот за кодирование отвечает операционная система и используемые в ней программы. Программа, отображающая этот текст на экране (текстовый редактор, браузер и т.п.), при разборе кода считывает кодировку очередного символа и ищет соответствующую ему векторную форму в нужном файле шрифта, который подключен для отображения данного текстового документа.
Значит, чтобы закодировать любой нужный нам символ (например, национального алфавита) должно быть выполнено два условия — векторная форма этого символа должна быть в используемом шрифте, и этот символ можно было бы закодировать в расширенных кодировках ASCII в один байт. Поэтому расширенных кодировок ASCII существует много.
Таблица ASCII
ASCII ‑ American standard code for information interchange – американский стандартный код обмена информацией.
ASCII – 8-ми разрядный код. Для кодирования символов используется 8 битов. С помощью 8 битов можно закодировать 256 символов. Но только первую половину кодовой таблицы (коды от 0 до 127) занимают полностью стандартизированные символы US-ASCII, а вторую (128 ‑ 255) — разные другие символы, часто соответствующие национальным стандартам. В настоящее время «ASCII» практически всегда означает «US-ASCII».
Таблица US-ASCII
.0 | .1 | .2 | .3 | .4 | .5 | .6 | .7 | .8 | .9 | .A | .B | .C | .D | .E | .F | |
0. | NUL | SOH | STX | ETX | EOT | ENQ | ACK | BEL | BS | TAB | LF | VT | FF | CR | SO | SI |
1. | DLE | DC1 | DC2 | DC3 | DC4 | NAK | SYN | ETB | CAN | EM | SUB | ESC | FS | GS | RS | US |
2. | ! | « | # | $ | % | & | ‘ | ( | ) | * | + | , | — | . | / | |
3. | : | ; | ? | |||||||||||||
4. | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
5. | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
6. | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
7. | p | q | r | s | t | u | v | w | x | y | z | < | | | > |
#include int main(void) |
Строка 1 — #include — означает «включи заголовок stdio.h». В файле с заголовком stdio.h объявляются функции, связанные с вводом и выводом данных. Аббревиатуру stdio можно перевести как стандартный ввод-вывод (англ. standard input/output). Буква «h» после точки означает заголовок (англ. header). В заголовках, которые, как правило, представлены отдельными заголовочными файлами, обычно объявляются предоставляемые соответствующими им библиотеками функции, типы данных, константы и определения препроцессора.
Строка 3 — определение функции main. Оно начинается с объявления:
что значит: «функция с именем main, которая не имеет аргументов (void) и возвращает целое число (число типа int от англ. integer)»
Английское слово void можно перевести как «пустота». Далее открывается фигурная скобка и идёт тело функции, в конце фигурная скобка закрывается. Тело функции определяет последовательность действий, выполняемых данной. В данном примере тело функции состоит из операторов в строках с 5-й по 10-ю.
Функция main() — главная функция программы, именно с нее начинается выполнение программы.
Строка 5 — объявление переменной c как без знаковой переменной целого типа char:
Переменная типа char имеет своим значением целое число unsigned char в диапазоне от 0 до 255. Но в операциях ввода-вывода переменные типа char могут быть представлены символами кодировочной таблицы ASCII. Поэтому, хотя для чтения значений переменных обычно используется функция scanf(), для чтения значений переменных типа char уместно использовать функцию getchar() (строка 6). Парная ей функция putchar()(строка 7) используется для вывода значения переменной типа char именно в виде символа кодировочной таблицы.
Строка 8 — стандартная функция форматированного вывода printf():
Строка в кавычках (строковая константа) задает формат вывода. Обратите внимание на комбинацию \n — она включает в выводимую строку управляющий код (или управляющий символ) перевода (также разрыва или завершения) строки. Комбинация, начинающаяся с символа %, определяет формат вывода значений переменных из списка, следующего после строки формата. Здесь список вывода состоит из двукратного повторения переменной c. В первый раз она выводится как символ, второй раз – как десятичное целое число – код символа. На скриншоте ниже в первой строке латинская буква A отобразилась как результат ввода с клавиатуры (действие в строке 6). Заметьте, что ввод символа A был завершен нажатием клавиши Enter, то есть вводом управляющего кода перевода строки. Во второй строке та же буква A появилась в результате действия putchar(c) в 7-й строке. Третья строка – результат действия printf(«\n%c %d\n», c, c) ‑ сначала выводится символ, потом его код.
Но в 9-й строке повторно указана инструкция getchar(). Она потребовалась для того, чтобы прочитать управляющий код перевода строки, которым был завершен ввод символа. Обычно такая инструкция используется для задержки окна работы программы.
При запуске программы непосредственно из графического окружения (в данном случае это среда Dev-Cpp), отведенное программе окно обычно закрывается сразу же после завершения программы. Функция getchar() ожидает ввод пользователя, тем самым «откладывая» завершение программы. Какие именно действия могут прервать это ожидание — зависит от системы, однако можно надеяться, что нажатие клавиши ⏎ Enter завершит эту функцию в любой системе.
В среде Dev-Cpp для задержки окна программы можно использовать функцию system(«PAUSE»). Именно она здесь используется и сообщение «Для продолжения нажмите любую клавишу…» ‑ это приглашение пользователю от функции system()завершить работу программы. Однако, если бы предыдущий getchar()не прочитал управляющий код, он был бы обработан системной функцией и завершил выполнение программы (инструкция return в 10-й строке).
Задания
1. Проверьте работу программы вводом символа B. Код этого символа равен 66.
2. По введенному символу получите следующий символ и его код. Не забывайте, что тип char – это числовой тип.
3. Разработайте вариант программы, выводящий код введенного символа в шестнадцатеричном и восьмеричном представлениях. (Указание: воспользуйтесь материалом Приложения 3)
4. Для символов, составляющих слово SUM, выведите сумму их кодов.
5. Для введенной прописной латинской буквы получите разность между кодом этой буквы и кодом буквы ‘A’.
6. Напишите программу, которая выведет четвертую, четырнадцатую и двадцать четвертую букву латинского алфавита.
7. Напишите программу, которая выведет подряд четыре буквы латинского алфавита, начиная с заданной буквы.
8. По введенной прописной латинской букве получите соответствующую строчную букву и ее код.
9. По введенной строчной латинской букве получите соответствующую прописную букву и ее код.
10. По введенной цифре получите ее код и разность между этой цифрой и нулем.
11. По введенной цифре, отличной от нуля и девяти, получите предыдущую и следующую цифру.
12. Для двух введенных цифр выведите их сумму (как сумму однозначных чисел) и сумму их кодов. Например, для цифр 5 и 6 их сумма равна 11, а сумма их кодов равна 107.
13. Попробуйте напечатать как символ число больше 255. Что получается?
Рекомендую к чтению материалы из Викиучебника— Язык Си в примерах
Кроме латиницы
Функция setlocale
#include char *setlocale(int type, const char *locale);
Функция setlocale() позволяет получить или установить некоторые параметры, которые зависят от геополитической среды выполнения программы. Если указатель locale является нулем, функция setlocale() возвращает указатель на строку текущей локализации. В противном случае функция setlocale() попытается использовать строку locale для установки локальных параметров в соответствии с параметром type. Для задания стандартных С-параметров региональной привязки используйте строку «С», а для задания собственных параметров среды — пустую строку («»). Чтобы получить подробную информацию о строках локализации, поддерживаемых конкретным компилятором, обратитесь к документации.
Стандарт предусматривает ряд средств для поддержки письменностей, отличных от «базовой» (26-символьной) латиницы. В основе такой поддержки — два следующих понятия:
1. локаль — набор сведений о письменности, языке и культуре, включающий, помимо прочего, таблицы соответствия символов верхнего и нижнего регистров;
2. широкие символьные типы (wchar_t, wint_t; англ. wide character) — для представления ряда письменностей (например — основанных на иероглифах), а равно для представления текстов на нескольких языках, «байтового» типа char оказывается недостаточно; как следствие, в задачах, связанных с обработкой многоязычных текстов, его заменяет тип wchar_t; аналогично, в операциях ввода-вывода используется тип wint_t (и константа WEOF.)
Соответственно, в исходный вариант вносятся следующие изменения.
1. Появляется вызов setlocale (LC_ALL, » «), инициализирующий локаль в соответствии с текущими настройками. (По умолчанию, при запуске программы полагается setlocale (LC_ALL, «C») — установка «стандартной» локали.) [5]
2. Функции getwchar, towupper, putwchar заменяют соответствующие для «узких» символов (getchar, toupper, putchar.) Соответственно меняются тип (int → wint_t) и константа признака исчерпания входного потока (EOF → WEOF.) [6] [7] [8]
3. Включаются соответствующие заголовки (locale.h, wchar.h, wctype.h.)
Отметим, впрочем, что принятые в конкретном языке правила обращения со строчными и заглавными могут оказаться сложнее простой зависимости символ → символ, предполагаемой в данном примере. Например, правила немецкого языка ставят в соответствие строчной «ß» пару заглавных — «SS» ( Straße → STRASSE), что ни коим образом не может быть реализовано функцией towupper.
Задания
1. Проверьте работу программы вводом строк Hello! и Привет!. Удостоверьтесь, что «базовые» варианты решения выполняют заданное преобразование лишь для для первой из них, в то время как «интернационализованное» решение действует и в отношении кириллического ввода.
2. Разработайте варианты программы, выполняющие (вновь для латиницы) a. преобразование верхнего регистра в нижний и b. «переключение» регистра — Hello! → hELLO!. (Указание: воспользуйтесь стандартными функциями islower и isupper. [9] [10] )
Кодировки
Всем рано или поздно приходится работать с различными кодировками. Заметив в коде своей команды различные, порой странные, подходы к решению этих проблем, пришлось провести разъяснительную беседу. Ниже поделюсь своим видением правильной работы с не-ASCII символами в коде. Буду рад конструктивной критике.
Принцип работы
Логика работы с различными кодировками в C++ проста и прозрачна. В общем виде она отражена в схеме. Программа работает в одной — своей внутренней кодировке, а правильно локализованные потоки отвечают за преобразование кодировки данных из внешнего кода во внутренний и обратно. Внутреннюю кодировку программы лучше всего зафиксировать раз и навсегда. Если программа работает с не-ASCII символами, то самый логичный выбор для внутренней кодировки — Юникод, причём использование UTF-8 и char для параметризации STL как правило неоправданно (хотя существуют ситуации, в которых это необходимо); более логично перейти на расширенные символы wchar_t и использовать UCS-2. За преобразование данных из внешней кодировки во внутреннюю отвечает фасет codecvt. Локализованные потоки сами вызовут соответствующие функции фасета при получении данных (о том кто такие фасеты я писал ранее).
Вышесказанное поясню комментированным примером, в котором прочитаем данные из cp1251 файла, покажем как boost::xpressive работает с юникодом и выведем кириллицу в cout в кодировке cp866 (консоль windows по умолчанию).
Кодировка исходников
Пример работы с различными кодировками
Ну вот и подобрались к самому интересному. Как я и говорил, код простой и понятный. Маленькое замечание по стандартным потокам — по умолчанию фасеты для них не задействуются так как они синхронизированы с stdio для производительности. Следует указать sync_with_stdio(false).
Фасет codecvt для преобразования кириллицы из cp1251 в ucs-2 и обратно
Примечания
Я не стал захламлять статью лишним кодом — фасет codecvt для cp866 реализуется аналогично, а о ctype я рассказывал ранее, но если кому-то нужен рабочий пример, эти фасеты можно взять на github — git://github.com/hoxnox/cyrillic-facets.git.
И прошу прощения за отсутствие номеров строк — чтобы НЛО «проглотило» топик пришлось сокращать highight кода.
Подробней о UNICODE модно почитать тут
Подробней о фасетах — в книге Страуструпа «Язык программирования C++», третье специальное издание, приложение
Подробней о boost::xpressive тут
UPD 20150813:
Хабрапользователь Cyapa провел расследование и выяснил, что фасет codecvt работает только с потоками, работающими с bisic_filebuf. Согласно стандарту (п. 27.9.1.1, кроме того это отмечено у Страуструпа) реализации не обязаны вызывать методы фасета codecvt для других буферов — в частности basic_stringbuf. Таким образом если вы создали локаль со своим фасетом codecvt и надеетесь, что std::stringstream, которому назначена эта локаль (с помощью imbue) будет дергать этот фасет, вы ошибаетесь.
Видео
Что такое ascii символы. ascii что это такое? Таблица ascii c++. C ++ Для начинающих. Урок #62Скачать
КАК РАБОТАЮТ КОДИРОВКИ | ОСНОВЫ ПРОГРАММИРОВАНИЯСкачать
Что такое таблица ASCII и как получить код символа на C#Скачать
Конспект лекции по Си: указатели, кодировка букв, строки, зачем & в scanf-е, а в printf - {b75ccae3bd172ebf9e243b7baacb30ddd0c1d39277627749d62145397f267824}d, {b75ccae3bd172ebf9e243b7baacb30ddd0c1d392Скачать
Решение проблемы с кодировкой КИРИЛЛИЦЫ в VSCODEСкачать
Программирование на Си урок 30: Функции ввода и вывода строк в языке СиСкачать
Язык Си для начинающих / #1 - Введение в язык СиСкачать
Java - урок 48.1 (Кодировка символов и строк)Скачать
Программирование на Си. #9. Особенности Char.Скачать
Язык Си для начинающих / #6 - Функции в СиСкачать