C ++ и UTF8 - почему бы просто не заменить ASCII? - PullRequest
9 голосов
/ 06 декабря 2011

В моем приложении мне приходится постоянно конвертировать строки между std::string и std::wstring из-за разных API (boost, win32, ffmpeg и т. Д.).Особенно при использовании ffmpeg строки заканчиваются на utf8-> utf16-> utf8-> utf16, просто чтобы открыть файл.

Поскольку UTF8 обратно совместим с ASCII, я подумал, что последовательно храню все свои строки UTF-8 std::string и конвертировать в std::wstring только когда мне нужно вызвать некоторые необычные функции.

Это сработало довольно хорошо, я реализовал to_lower, to_upper, т.е. quals для utf8.Однако потом я встретил несколько тупиков std :: regex и регулярные сравнения строк.Чтобы это можно было использовать, мне нужно было бы реализовать пользовательский класс ustring на основе std :: string с повторной реализацией всех соответствующих алгоритмов (включая регулярное выражение).

В основном мой вывод заключается в том, что utf8 не очень хорошдля общего пользования.И текущий std::string/std::wstring беспорядок.

Однако мой вопрос заключается в том, почему значения по умолчанию std::string и "" не просто изменены для использования UTF8?Тем более, что UTF8 обратно совместим?Есть ли какой-нибудь флаг компилятора, который может это сделать?Конечно, реализацию stl нужно будет автоматически адаптировать.

Я смотрел на ICU, но он не очень совместим с apis, предполагая basic_string, например, без begin / end / c_str и т. Д. *

Ответы [ 3 ]

8 голосов
/ 06 декабря 2011

Основная проблема - это смешение представления и кодировки в памяти.

Ни одна из кодировок Unicode действительно не поддается обработке текста.В целом пользователи будут заботиться о графемах (что на экране), в то время как кодировка определяется в виде кодовых точек ... а некоторые графемы состоят из нескольких кодовых точек.

Таким образом, когда кто-то спрашивает: чтоявляется 5-м символом "Hélène" (французское имя), вопрос довольно запутанный:

  • С точки зрения графем ответ: n.
  • С точки зрения кодаточки ... это зависит от представления é и è (они могут быть представлены либо в виде одной кодовой точки, либо в виде пары, используя диакритические знаки ...)

В зависимости отисточник вопроса (конечный пользователь перед ее экраном или процедура кодирования), ответ совершенно другой.

Поэтому я думаю, что реальный вопрос - Почему мы говорим о кодировках здесь?

Сегодня это не имеет смысла, и нам потребуются два «представления»: графемы и кодовые точки.

К сожалению, интерфейсы std::string и std::wstring были унаследованы оттигде люди считали, что ASCII было достаточно, и достигнутый прогресс на самом деле не решил проблему.

Я даже не понимаю, почему следует указывать представление в памяти, это деталь реализации.Все, что нужно пользователю, это:

  • , чтобы иметь возможность читать / писать в UTF- * и ASCII
  • , чтобы иметь возможность работать с графемами
  • , чтобы бытьвозможность редактировать графемы (для управления диакритическими знаками)

... кого волнует, как она представлена?Я думал, что хорошее программное обеспечение было построено на инкапсуляции?

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

3 голосов
/ 06 декабря 2011

Есть две проблемы с использованием UTF8 в Windows.

  1. Вы не можете сказать, сколько байтов займет строка - это зависит от того, какие символы присутствуют, поскольку некоторые символы занимают 1 байт, некоторые - 2, некоторые - 3, а некоторые - 4.

  2. Windows API использует UTF16. Так как большинство программ для Windows делают многочисленные вызовы Windows API, существует много затрат на конвертацию назад и вперед. (Обратите внимание, что вы можете сделать сборку «не в Юникоде», которая выглядит так, как будто она использует api окон utf8, но все, что происходит, это то, что преобразование назад и вперед при каждом вызове скрыто)

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

Так что же делать? Я использую UTF16 везде "внутри" всех моих программ. Когда строковые данные должны быть сохранены в файле или переданы из сокета, я сначала преобразовываю их в UTF8.

Это означает, что 95% моего кода выполняется просто и наиболее эффективно, и все грязные преобразования между UTF8 и UTF16 могут быть изолированы для подпрограмм, отвечающих за ввод / вывод.

3 голосов
/ 06 декабря 2011

Вы не можете, основная причина этого называется Microsoft .Они решили не поддерживать Unicode как UTF-8, поэтому поддержка UTF-8 в Windows минимальна.

В Windows вы не можете использовать UTF-8 в качестве кодовой страницы, но вы можете конвертировать из или в UTF-8.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...