Char arr[]={"Кириллица Latin"};
Я пользовался всегда UTF16 широкими символами, хочу перейти на UTF8.
В UTF8 количество Байт на символ различаются, поэтому количество Байт в массиве не соответствует количеству символов в массиве.
Есть ли простой способ узнать количество символов в UTF8 массиве?
И ещё как можно например сравнить элемент UTF8 массива с чем либо?
Например if(arr[0]==L'Я')
Так ведь не получится, потому что буква Я занимает 2 Байта.
Мне кажется или UTF8 очень неудобный?
C/C++
Как узнать количество символов в UTF8 массиве?(Си)
Есть разные подходы.
1. Выполнять обработку строк в UTF-16 или (лучше) в UTF-32. Если данные в UTF-8, они преобразуются в одну из этих кодировок. В UTF-16 один символ может кодироваться парой кодов. В UTF-32 такого нет.
2. Использовать специальные функции для работы с UTF-8, или самому написать соответствующий код. В этом случае русская буква - это не символ, а строка.
Для того чтоб пробежаться по строке, ты привык использовать инкремент индекса. При работе с UTF-8 последовательно определяют длину каждого символа, так перебирают символы строки.
Функция mblen возвращает длину символа в байтах
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mbclen-mblen-mblen-l
Пишут, что mblen может возвращать значение до 3. Это странно, поскольку в UTF-8 символ может кодироваться 4 байтами.
1. Выполнять обработку строк в UTF-16 или (лучше) в UTF-32. Если данные в UTF-8, они преобразуются в одну из этих кодировок. В UTF-16 один символ может кодироваться парой кодов. В UTF-32 такого нет.
2. Использовать специальные функции для работы с UTF-8, или самому написать соответствующий код. В этом случае русская буква - это не символ, а строка.
Для того чтоб пробежаться по строке, ты привык использовать инкремент индекса. При работе с UTF-8 последовательно определяют длину каждого символа, так перебирают символы строки.
Функция mblen возвращает длину символа в байтах
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mbclen-mblen-mblen-l
Пишут, что mblen может возвращать значение до 3. Это странно, поскольку в UTF-8 символ может кодироваться 4 байтами.
Можно сделать по-хитрому! Смотри как. Чтобы это что-либо было тоже в UTF-8! Можно заставить работать Студию в UTF-8, есть специальные настройки для редактора и компилятора. Компилер ресурсов тоже прекрасно работает с UTF-8, главное включить соответствующую опцию. (Про Линукс объяснять не буду, там UTF-8 из коробки.) Вот и всё. БААМ, и в программе и в тексте у тебя везде UTF-8, и тебе тогда нужно просто заюзать стандартную memcmp(). Единственная проблема: узнать длинну символа. Тебе нужно будет написать свою функцию для этого. (смотри Википедию) А на основе её, ещё функцию длины строки. И на 99% это покроет все варианты. За исключением лексики, таких, как: tolower(), toupper() и т. д. (Хотя, в десятке могли поддержку уже добавить, я не слежу за этим...)
Похожие вопросы
- Strlen для int массивов.(Си)
- Откуда мусор в массиве? (Си)
- Указатель превращается в двумерный массив. (Си)
- Дан целочисленный массив с количеством элементов п. Сжать массив, выбросив из него каждый второй элемент.
- Почему не правильно записывается массив?(СИ)
- Отображение символов UTF8 в консоли Windows. (Си)
- Двумерный динамический массив с неизвестны количеством столбиков или строк
- Упорядочить элементы массива по возрастанию на языке Си
- Помогите добавить ввод чисел в массив матрицы на языке Си
- Как в функции распечатать двумерный динамический массив в Си
Пишут что для mblen нужна setlocale, я её вставил тоже.
mblen получает в качестве параметра массив и возвращает количество Байт на 1 символ??
А если в массиве разные типы символов с разным количеством Байт на символ?
Н всё равно неправильно выводит количество Байт даже только для кириллицы у меня. Выводит 1 Байт для кириллицы. Неправильно. Должно быть 2 Байта на символ.
Кодировку и Байты я проверял.
Может что то не так делаю?
setlocale(LC_ALL, ".1251");
char arr[]={"Кириллица Latin"};
printf("%d\n", mblen(arr, 2));
Для этих типов куча своих аналогов функций и многие из них не кроссплатформенные.
32 бита насимвол слишком много
Получается вместо этого if(arr[0]==L'Я') надо писать код на 100 строк?
Да, я догадался, но у меня 1 выводит на кириллицу.
А онлайн компилятор 2 Байта выводит https://onlinegdb.com/sFoG9WHUt
У меня UTF8 массив
У меня UTF8, я её выставлял
Например ко коду, который получается у символа К.
Только в UTF8 такой код у этого символа
В Visual Studio кодировка в utf8 переводится, а в других компиляторах видимо нет.
char*p=setlocale(LC_ALL, ".utf8");
printf("%s\n", p);
Значит видимо раньше этой поддержки не было. Может в других компиляторах её до сих пор и нет.
Пост 2019 года.
То есть из utf8 массива побайтово копировать указанное количество Байт.
Это бы сильно облегчило работу с utf8 массивом.
Но всё же с ней не всё так хорошо. Если копируешь часть utf8 массива, а не весь, то может вывестись мусор в конце.
https://docs.microsoft.com/ru-ru/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=msvc-170
начиная с версии Windows 10 1803 (10.0.17134.0), универсальная среда выполнения C поддерживает использование кодовой страницы UTF-8. Это означает, что char строки, передаваемые в функции среды выполнения C, будут ждать строк в кодировке UTF-8. Чтобы включить режим UTF-8, используйте ".UTF8" в качестве кодовой страницы при использовании setlocale . например, setlocale(LC_ALL, ".UTF8") будет использовать текущую стандартную кодовую страницу ANSI Windows (ACP) для языкового стандарта и кодировку UTF-8 для кодовой страницы.