#cpp #c
Как получается что русские символы умещаются в C строке в кодировке UTF-8 когда каждый русский символ в этой кодировке занимает 2 байта, а ячейка в C строке вмещает только 1 байт? Почему если выводить эту строку, то она выведется без проблем, а если выводить её посимвольно, то она выводит ошибки? Ещё если можно, то посоветуйте материалов почитать по этой теме. char a[] = "Строка"; std::cout << a << std::endl; for (int i = 0; i < 6; i++) std::cout << a[i] << std::endl;
Ответы
Ответ 1
Чудес не бывает - символы, занимающие больше одного байта в Си так же занимают больше одного байта. В случае со строкой char они лежат в нескольких ячейках (в случае с двухбайтными - первый символ лежит в первых двух, второй - во вторых двух). Если говорить о C++, то для многобайтных символов есть специальный тип wchar_t, который имеет размер в 4 байта для GNU/Linux и 2 байта для Windows API Аналогом std::string для этого типа является std::wstring. http://en.cppreference.com/w/cpp/string/basic_string // сперва считаем символ беззнаковым, потом переводим его в целое число char a[] = "Строка"; std::cout << (int)(unsigned char)a[0] << "; " << (int)(unsigned char)a[1] << std::endl; Выведет 208; 161 (https://ideone.com/FyUdhj) Согласно вот это (https://unicode-table.com/ru/0421/) таблице, символ С в UTF-8 представляется двумя байтами, как раз 208 161Ответ 2
Ячейка в С-строке вмещает, конечно, один байт, но каждый символ в таком случае будет занимать в ней два места. И длина всей строки -- 12 char a[] = "Строка"; std::cout << a << ' ' << strlen(a) << std::endl; // Строка 12 Например, если вывести из этой строки по два символа, то выведутся правильные символы: for (int i = 0; i < 6; i++) std::cout << a[2*i] << a[2*i+1] << std::endl; utf-8 -- мультибайтовая кодировка (разные символы могут занимать разное количество байт). В том числе кириллические символы будут занимать два байта. При инициализации строки каждый по два байта и займёт. Следующие две конструкции с точки зрения языка эквивалентны: char a[] = "\xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0"; char a[] = "Строка";
Комментариев нет:
Отправить комментарий