и UTF-8 в Linux.
Это в основном верно для современного Linux.На самом деле кодировка зависит от того, какой API или библиотека используется.Некоторые жестко запрограммированы на использование UTF-8.Но некоторые читают переменные окружения LC_ALL, LC_CTYPE или LANG для определения используемой кодировки (например, библиотеки Qt).Так что будьте осторожны.
Мы не можем решить, будет ли лучший подход
Как обычно, это зависит.
Если 90% кода будет иметь делосо специфичным для платформы API конкретным способом, очевидно, лучше использовать специфичные для платформы строки.В качестве примера - драйвер устройства или собственное приложение iOS.
Если 90% кода представляет собой сложную бизнес-логику, которая является общей для разных платформ, очевидно, что лучше использовать одну и ту же кодировку на всех платформах.В качестве примера - клиент чата или браузер.
Во втором случае у вас есть выбор:
- Использовать кроссплатформенную библиотеку, которая обеспечивает поддержку строк (например, Qt, ICU)
- Используйте голые указатели (я считаю, что std :: string также «голым указателем»)
Если работа со строками является важной частью вашего приложения, выбор хорошей библиотеки для строкхороший ход.Например, Qt имеет очень солидный набор классов, который покрывает 99% общих задач.К сожалению, у меня нет опыта работы с ICU, но он также выглядит очень хорошо.
При использовании некоторой библиотеки для строк вам нужно заботиться о кодировании только при работе с внешними библиотеками, API платформы или отправке строк по сети (илидиск).Например, многие программисты на Cocoa, C # или Qt (у всех есть поддержка сплошных строк) очень мало знают о деталях кодирования (и это хорошо, поскольку они могут сосредоточиться на своей основной задаче).
Мой опыт вработа со строками - немного , поэтому я лично предпочитаю голые указатели.Код, который их использует, очень переносим (в том смысле, что его можно легко использовать в других проектах и платформах), поскольку имеет меньше внешних зависимостей.Это также очень просто и быстро (но, чтобы почувствовать это, вероятно, понадобится некоторый опыт и опыт работы с Unicode).
Я согласен, что подход с голыми указателями подходит не для всех.Это хорошо, когда:
- Вы работаете со всеми строками, а разделение, поиск, сравнение - редкая задача
- Вы можете использовать одинаковую кодировку во всех компонентах и нуждаетесь в преобразовании только при использованииAPI платформы
- Все ваши поддерживаемые платформы имеют API для:
- Преобразования из вашей кодировки в ту, которая используется в API
- Преобразование из кодировки API в ту, которая используется в вашем коде
- Указатели не являются проблемой в вашей команде
Из моего небольшого конкретного опыта это на самом деле очень распространенный случай.
При работе с голыми указателями целесообразно выбирать кодировку, которая будет использоваться во всем проекте (или во всех проектах).
С моей точки зрения, UTF-8 является абсолютным победителем.Если вы не можете использовать UTF-8 - используйте библиотеку строк или API платформы для строк - это сэкономит вам много времени.
Преимущества UTF-8:
- ПолностьюСовместим с ASCII.Любая строка ASCII является допустимой строкой UTF-8.
- Библиотека C std прекрасно работает со строками UTF-8.(*)
- Библиотека C ++ std прекрасно работает с UTF-8 (std :: string и friends).(*)
- Устаревший код прекрасно работает с UTF-8.
- Практически любая платформа поддерживает UTF-8.
- Отладка НАМНОГО проще с UTF-8 (так какСовместим с ASCII).
- Нет беспорядка Little-Endian / Big-Endian.
- Вы не заметите классическую ошибку "О, UTF-16 не всегда 2 байта?".
(*) До тех пор, пока вам не понадобится их лексическое сравнение, преобразуйте регистр (toUpper / toLower), измените форму нормализации или что-то в этом роде - если вы это сделаете - используйте библиотеку строк или API платформы.
Недостаток сомнителен:
- Менее компактен для китайского языка (и других символов с большими номерами кодовых точек), чем UTF-16.
- Труднее (немного на самом деле) перебирать символы.
Итак, я рекомендую использовать UTF-8 в качестве обычной кодировки для проектов, которые не используют библиотеку строк.
Но кодирование - не единственный вопрос, на который вам нужно ответить.
Существует такая вещь, как нормализация . Проще говоря, некоторые буквы могут быть представлены несколькими способами - как один глиф или как комбинация разных глифов. Общая проблема заключается в том, что большинство функций сравнения строк обрабатывают их как разные символы. Если вы работаете над кроссплатформенным проектом, выбор одной из форм нормализации в качестве стандартного является правильным решением. Это сэкономит ваше время.
Например, если пароль пользователя содержит «йёжиг», он будет представлен по-разному (как в UTF-8, так и в UTF-16) при вводе на Mac (который в основном использует форму нормализации D) и в Windows (которая больше всего любит форму нормализации C ). Поэтому, если пользователь, зарегистрированный под Windows с таким паролем, будет проблематично войти в систему под Mac.
Кроме того, я бы не рекомендовал использовать wchar_t (или использовать его только в коде Windows как тип символов UCS-2 / UTF-16). Проблема с wchar_t заключается в том, что с ним нет кодировки. Это просто абстрактный широкий символ, который больше нормального символа (16 бит в Windows, 32 бита в большинстве * nix).