Кроссплатформенные строки (и Unicode) в C ++ - PullRequest
12 голосов
/ 13 ноября 2010

Итак, я наконец-то вернулся к своей главной задаче - портированию довольно большого проекта C ++ с Windows на Mac.

Сразу же я столкнулся с проблемой, когда wchar_t имеет 16-битное значение.Windows, но 32-разрядная на Mac.Это проблема, потому что все строки представлены как wchar_t, и между компьютерами Windows и Mac будут передаваться строковые данные в обе стороны (как на дисковых данных, так и в сетевых данных).Из-за того, как он работает, было бы не совсем просто преобразовать строки в какой-то общий формат перед отправкой и получением данных.

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

Теперь я мог бы объединить здесь несколько идей и создать для себя больше проблем, чем нужновот почему я задаю этот вопрос.Мы думаем, что сохранение всех наших строковых данных в памяти как UTF-8 имеет большой смысл.Это решает проблему wchar_t, связанную с различными размерами, это означает, что мы можем легко поддерживать несколько языков, и это также значительно сокращает объем используемой памяти (у нас МНОГО - в основном английские - загруженные строки) - но не похоже, что многие люди делаютэтот.Мы что-то упустили?Есть очевидная проблема, с которой вам приходится сталкиваться, когда длина строки может быть меньше размера памяти, в котором хранятся эти строковые данные.

Или использование UTF-16 - лучшая идея?Или мы должны придерживаться wchar_t и писать код для преобразования между wchar_t и, скажем, Unicode в местах, где мы читаем / пишем на диск или в сеть?

Я понимаю, что это опасно близко к тому, чтобы спрашивать мнения - номы нервничаем из-за того, что упускаем из виду что-то очевидное, потому что не похоже, что есть много строковых классов Unicode (например) - но все же есть много кода для преобразования в / из Unicode, как в boost :: locale, iconv,utf-cpp и ICU.

Ответы [ 4 ]

8 голосов
/ 13 ноября 2010

Всегда используйте протокол, определенный для байта, когда используется файл или сетевое соединение.Не полагайтесь на то, как компилятор C ++ хранит что-либо в памяти.Для текста Unicode это означает выбор как кодировки, так и порядка байтов (хорошо, UTF-8 не заботится о порядке байтов).Даже если платформы, которые вы в настоящее время хотите поддерживать, имеют схожие архитектуры, вероятно, появится другая популярная платформа с другим поведением или даже новая ОС для одной из существующих платформ, и вы будете рады, что написали переносимый код.

2 голосов
/ 13 ноября 2010

Я склонен использовать UTF-8 в качестве внутреннего представления.Вы теряете только проверку длины строки, в любом случае она не очень полезна.Для преобразования Windows API я использую свои собственные функции преобразования Win32 Я разработал здесь .Как Mac и Linux (для большей части стандарт с учетом UTF-8, нет необходимости конвертировать что-нибудь там).Бесплатные бонусы, которые вы получаете:

  1. используйте старые добрые std::string.
  2. побайтный сетевой / потоковый транспорт.
  3. Для большинства языков достаточно памяти.1013 *
  4. Для большей функциональности: utf8cpp
1 голос
/ 14 ноября 2010

ICU имеет строковый класс C ++, UnicodeString

1 голос
/ 13 ноября 2010

Практическое правило: UTF-16 для обработки, UTF-8 для связи и хранения.

Конечно, любое правило может быть нарушено, и это правило не вырезано в камне.Но вы должны знать, когда можно его сломать.

Например, было бы неплохо использовать что-то еще, если среда, которую вы используете, хочет чего-то другого.Но API Mac OS X используют UTF-16, как и Windows.Так что UTF-16 имеет больше смысла.Конвертировать более просто, прежде чем помещать / получать данные в сети (потому что вы, вероятно, делаете это за 2-3 подпрограммы), чем выполнять все преобразования для вызова API-интерфейсов ОС.вы развиваетесь.Если это что-то с очень небольшой обработкой текста и очень маленькими обращениями к системе (что-то вроде почтового сервера, который в основном перемещает вещи, не меняя их), тогда UTF-8 может быть хорошим выбором.Как бы вы ни ненавидели этот ответ, «это зависит».

...