Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Русская строка в C

#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[] = "Строка";

Комментариев нет:

Отправить комментарий