Вопрос

У нас есть набор приложений, которые были разработаны для набора символов ASCII.Теперь мы пытаемся установить его в Исландии и сталкиваемся с проблемами, связанными с неправильным использованием исландских символов.

Мы решаем наши проблемы, но мне было интересно:Есть ли хорошее "руководство" для написания кода на C ++, который предназначен для 8-битных символов и который будет работать должным образом, когда ему будут переданы данные UTF-8?

Я не могу ожидать, что все прочитают весь стандарт Unicode, но если есть что-то более удобоваримое, я бы хотел поделиться этим с командой, чтобы мы больше не сталкивались с подобными проблемами.

Переписать все приложения для использования wchar_t или какого-либо другого строкового представления на данный момент невозможно.Я также отмечу, что эти приложения взаимодействуют по сетям с серверами и устройствами, использующими 8-разрядные символы, поэтому, даже если бы мы использовали Юникод внутри компании, у нас все равно были бы проблемы с переводом на границах.По большей части эти приложения просто передают данные по кругу;они не "обрабатывают" текст каким-либо иным способом, кроме копирования его с места на место.

Используемые операционные системы - Windows и Linux.Мы используем std::string и обычные строки C.(И не просите меня защищать какие-либо дизайнерские решения.Я просто пытаюсь помочь исправить этот беспорядок.)


Вот список того, что было предложено:

Это было полезно?

Решение

Это выглядит как исчерпывающее краткое руководство:
http://www.cl.cam.ac.uk /~mgk25/unicode.html

Другие советы

Просто будьте 8-битно чистыми, по большей части.Однако вы должны знать, что любой символ, отличный от ASCII, разбивается на несколько байтов, поэтому вы должны учитывать это при разбиении текста на строки или усечении текста для отображения.

Преимущество UTF-8 в том, что вы всегда можете определить, где вы находитесь, по многобайтовому символу:если установлен бит 7 и сброшен бит 6 (байт равен 0x80-0xBF), это завершающий байт, в то время как если установлены биты 7 и 6 и сброшен 5 (0xC0-0xDF), это начальный байт с одним завершающим байтом;если заданы 7, 6 и 5, а 4 сброшено (0xE0-0xEF), то это начальный байт с двумя конечными байтами и так далее.Количество последовательных битов, установленных в старшем значащем бите, - это общее количество байтов, составляющих символ.Это:

110x xxxx = двухбайтовый символ.
1110 xxxx = трехбайтовый символ.
1111 0xxx = четырехбайтовый символ
и т.д.

Весь исландский алфавит содержится в стандарте ISO 8859-1 и, следовательно, в Windows-1252.Если это приложение консольного режима, имейте в виду, что консоль использует кодовые страницы IBM, поэтому (в зависимости от языкового стандарта системы) оно может отображаться в 437, 850 или 861.Windows не имеет встроенной поддержки отображения UTF-8;вы должны преобразовать в UTF-16 и использовать API-интерфейсы Unicode.

Вызов SetConsoleCP и SetConsoleOutputCP с указанием кодовой страницы 1252 поможет решить вашу проблему, если это приложение консольного режима.К сожалению, выбранный консольный шрифт должен быть шрифтом, поддерживающим кодовую страницу, и я не вижу способа установить шрифт.Стандартные растровые шрифты поддерживают только системную OEM-кодовую страницу по умолчанию.

Имейте в виду, что полный юникод не умещается в 16-битных символах;поэтому либо используйте 32-битные символы, либо кодировку переменной ширины (UTF-8 является наиболее популярным).

UTF-8 был разработан именно с учетом ваших проблем.Одна вещь, с которой я был бы осторожен, это то, что ASCII на самом деле является 7-битной кодировкой, поэтому, если какая-либо часть вашей инфраструктуры использует 8-й бит для других целей, это может быть сложно.

Возможно, вы захотите проверить отделение интенсивной терапии.У них могут быть доступные функции, которые упростили бы работу со строками UTF-8.

Исландский использует ISO Latin 1, так что восьми бит должно быть достаточно.Нам нужно больше деталей, чтобы понять, что происходит.

Исландский, как и французский, немецкий и большинство других языков Западной Европы, может поддерживаться с использованием 8-разрядного набора символов (CP1252 в Windows, ISO 8859-1, также известный как Latin1 в *x).Это был стандартный подход до изобретения Unicode и до сих пор является довольно распространенным.Как вы говорите, у вас есть ограничение, согласно которому вы не можете переписать свое приложение для использования wchar, да вам и не нужно этого делать.

Вы не должны удивляться, что UTF-8 вызывает проблемы;UTF-8 кодирует символы, отличные от ASCII (напримерлатинские символы с ударением, thorn, eth и т.д.) по ДВА БАЙТА каждый.

Единственный общий совет, который можно дать, довольно прост (теоретически).:(1) решите, какой набор символов вы собираетесь поддерживать (Unicode, Latin1, CP1252, ...) в вашей системе (2) если вам предоставляются данные, закодированные каким-либо другим способом (напримерUTF-8) затем перекодируйте его в ваш стандарт (напримерCP1252) на границе системы (3) если вам необходимо предоставить данные, закодированные каким-либо другим способом, ...

Возможно, вы захотите использовать широкие символы (wchar_t вместо char и std::wstring вместо std::string).Это не решает автоматически 100% ваших проблем, но является хорошим первым шагом.

Также используйте строковые функции, поддерживающие Unicode (см. документацию).Если что-то манипулирует широкими символами или строкой, оно, как правило, осознает, что они широкие.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top