Должен ли UTF-16 считаться вредным?

Я собираюсь спросить, что, вероятно, довольно спорный вопрос: «Если один из самых популярные кодировки, UTF-16, считаются вредными? »

Почему я задаю этот вопрос?

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

Я знаю; множество приложений, фреймворков и API-интерфейсов используют UTF-16, такие как String String, C # String, Win32 API, библиотеки графического интерфейса Qt, библиотека Unicode ICU и т. д. Однако при этом существует множество основных ошибок в обработке символов из BMP (символы, которые должны быть закодированы с использованием двух элементов UTF-16).

Например, попробуйте отредактировать один из следующих символов:

433 голоса | спросил 4 revs, 3 users 66%
Artyom
1 Jam1000000amThu, 01 Jan 1970 03:00:00 +030070 1970, 03:00:00

20 ответов


341
  

Это старый ответ.
  Для получения последних обновлений см. UTF-8 в любом месте .

Мнение: Да, UTF-16 следует считать вредным . Сама причина, по которой она существует, заключается в том, что некоторое время назад имело место ошибочное убеждение в том, что широкоформатная версия будет теперь UCS-4.

Несмотря на «англо-центризм» UTF-8, его следует рассматривать как единственную полезную кодировку для текста. Можно утверждать, что исходные коды программ, веб-страниц и XML-файлов, имена файлов ОС и другие текстовые интерфейсы от компьютера до компьютера никогда не должны существовать. Но когда они это делают, текст не только для читателей.

С другой стороны, накладные расходы UTF-8 - небольшая цена для оплаты, в то время как у нее есть значительные преимущества. Преимущества, такие как совместимость с неосновным кодом, который просто передает строки с помощью char*. Это замечательно. В UTF-16 есть несколько полезных символов, которые являются SHORTER в UTF-16, чем в UTF-8.

Я считаю, что все остальные кодировки умрут в конце концов. Это связано с тем, что MS-Windows, Java, ICU, python перестают использовать его в качестве своего любимого. После долгих исследований и обсуждений конвенции по развитию в моей компании запретили использование UTF-16 в любом месте, кроме вызовов API OS, и это несмотря на важность производительности в наших приложений и того факта, что мы используем Windows. Функции преобразования были разработаны для преобразования всегда предполагаемого-UTF8 std::string s в собственный UTF-16, который сам по себе не поддерживается должным образом .

Для людей, которые говорят: « используйте то, что нужно там, где это необходимо », я говорю: есть огромное преимущество в использовании одной и той же кодировки везде, и я не вижу достаточных оснований для этого. В частности, я думаю, что добавление wchar_t в C ++ было ошибкой, а также дополнениями Unicode к C ++ 0x. Однако из STL-реализаций требуется, чтобы каждый параметр std::string или char* считался совместимым с unicode.

Я также против подхода « использовать то, что вы хотите ». Я не вижу причин для такой свободы. Там достаточно путаницы в отношении текста, в результате чего все это сломанное программное обеспечение. Выше сказанное, я убежден, что программисты должны, наконец, достичь единодушного согласия по UTF-8. (Я родом из страны, не относящейся к аскейскому языку, и вырос в Windows, поэтому в последний раз я ожидал нападения на UTF-16 по религиозным мотивам).

Я хотел бы поделиться дополнительной информацией о том, как я делаю текст в Windows, и о том, что я рекомендую всем остальным для проверки правильности юникода во время компиляции, простоты использования и лучшей многоплатформенности кода. Это предложение существенно отличается от того, что обычно рекомендуется в качестве правильного способа использования Unicode в окнах. Тем не менее, углубленное исследование этих рекомендаций привело к такому же выводу. Итак, вот:

  • Не используйте wchar_t или std::wstring в любом месте, кроме смежной точки, к API, принимающим UTF-16.
  • Не используйте символы _T("") или L"" UTF-16 (они должны быть исключены из стандарта, как часть UTF -16).
  • Не используйте типы, функции или их производные, которые чувствительны к константе _UNICODE, например LPTSTR или CreateWindow().
  • Тем не менее, _UNICODE всегда задан, чтобы избежать передачи строк char* в WinAPI, который будет скомпилирован без комментариев
  • std::strings и char* в любом месте программы считаются UTF-8 (если не указано иное)
  • Все мои строки std::string, хотя вы можете передать char * или строковый литерал в convert(const std::string &).
  • используют только функции Win32, которые принимают широкоформатные (LPWSTR). Никогда не поддерживаются LPTSTR или LPSTR. Передайте параметры следующим образом:

    ::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str())
    

    (Политика использует функции преобразования ниже.)

  • С строками MFC:

    CString someoneElse; // something that arrived from MFC. Converted as soon as possible, before passing any further away from the API call:
    
    std::string s = str(boost::format("Hello %s\n") % Convert(someoneElse));
    AfxMessageBox(MfcUtils::Convert(s), _T("Error"), MB_OK);
    
  • Работа с файлами, именами файлов и файлами в Windows:

    • Никогда не передавайте std::string или const char* аргументы имени файла в семейство fstream. MSVC STL не поддерживает аргументы UTF-8, но имеет нестандартное расширение, которое должно использоваться следующим образом:
    • Преобразуйте аргументы std::string в std::wstring с помощью Utils::Convert:

      std::ifstream ifs(Utils::Convert("hello"),
                        std::ios_base::in |
                        std::ios_base::binary);
      

      Нам придется вручную удалить конвертер, когда изменится отношение MSVC к fstream.

    • Этот код не является многоплатформенным и может потребоваться изменить вручную в будущем.
    • Дополнительную информацию см. в разделе fstream unicode research /обсуждение 4215.
    • Никогда не создавайте текстовые выходные файлы с содержимым, отличным от UTF8
    • Избегайте использования fopen() для причин RAII /OOD. При необходимости используйте _wfopen() и соглашения WinAPI выше.

// For interface to win32 API functions
std::string convert(const std::wstring& str, unsigned int codePage /*= CP_UTF8*/)
{
    // Ask me for implementation..
    ...
}

std::wstring convert(const std::string& str, unsigned int codePage /*= CP_UTF8*/)
{
    // Ask me for implementation..
    ...
}

// Interface to MFC
std::string convert(const CString &mfcString)
{
#ifdef UNICODE
    return Utils::convert(std::wstring(mfcString.GetString()));
#else
    return mfcString.GetString();   // This branch is deprecated.
#endif
}

CString convert(const std::string &s)
{
#ifdef UNICODE
    return CString(Utils::convert(s).c_str());
#else
    Exceptions::Assert(false, "Unicode policy violation. See W569"); // This branch is deprecated as it does not support unicode
    return s.c_str();   
#endif
}
ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
158

Кодовые страницы Unicode не являются символами! Иногда это даже не глифы (визуальные формы).

Некоторые примеры:

  • Римские цифровые коды, такие как «â ... ²». (Один символ, который выглядит как «iii».)
  • Акцентированные символы, такие как «Ã¡», которые могут быть представлены как один комбинированный символ «\ u00e1» или символ и разделенный диакритический «\ u0061 \ u0301».
  • Символы, такие как греческая строчная сигма, которые имеют разные формы для средних («Ïƒ») и конечных («Ï») позиций слов, но которые следует рассматривать как синонимы для поиска.
  • Unicode дискретный дефис U + 00AD, который может отображаться или не отображаться визуально в зависимости от контекста и который игнорируется для семантического поиска.

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

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
54

Существует простое правило о том, какую форму преобразования Unicode (UTF) использовать:  - utf-8 для хранения и связи  - utf-16 для обработки данных  - вы можете пойти с utf-32, если большая часть используемого API платформы - utf-32 (обычно в мире UNIX).

В большинстве систем сегодня используются utf-16 (Windows, Mac OS, Java, .NET, ICU, Qt). Также см. Этот документ: http://unicode.org/notes/tn12/

Вернуться к «UTF-16 как вредный», я бы сказал: определенно не.

Люди, которые боятся суррогатов (думая, что они преобразуют Unicode в кодировку с переменной длиной), не понимают других (более крупных) сложностей, которые делают отображение между символами и кодовой точкой Юникода очень сложным: объединение символов, лигатур , селектора вариаций, управляющие символы и т. д.

Просто прочитайте эту серию здесь http://www.siao2.com/2009 /06/29/9800913.aspx и посмотреть, как UTF-16 становится легкой проблемой.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
43

Да, абсолютно.

Почему? Это связано с выполнением кода .

Если вы посмотрите на эти статистика использования кодовых страниц на большом корпусе от Tom Christiansen вы увидите, что транс-8-битные коды BMP используются несколько порядков, если величина больше, чем не BMP-коды:

 2663710 U+002013 ‹–›  GC=Pd    EN DASH
 1065594 U+0000A0 ‹ ›  GC=Zs    NO-BREAK SPACE
 1009762 U+0000B1 ‹±›  GC=Sm    PLUS-MINUS SIGN
  784139 U+002212 ‹−›  GC=Sm    MINUS SIGN
  602377 U+002003 ‹ ›  GC=Zs    EM SPACE

 544 U+01D49E ‹
ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
40

Я бы предположил, что мышление UTF-16 может считаться вредным, говорит, что вам нужно получить большее понимание unicode .

С тех пор, как я был замешан для того, чтобы изложить свое мнение по субъективному вопросу, позвольте мне уточнить. Что именно вас беспокоит UTF-16? Вы предпочли бы, чтобы все было закодировано в UTF-8? UTF-7? Или как насчет UCS-4? Конечно, некоторые приложения не предназначены для обработки вездесущего кода символов, но они необходимы, особенно в сегодняшней глобальной информационной области, для связи между международными границами.

Но на самом деле, если вы считаете, что UTF-16 следует считать вредным, потому что он запутан или может быть неправильно реализован (возможно, unicode может быть), то какой метод кодирования символов будет считаться не вредным?

РЕДАКТИРОВАТЬ: Прояснить: зачем считать неправильные реализации стандарта отражением качества самого стандарта? Как отмечали другие, только потому, что приложение неправильно использует инструмент, это не означает, что сам инструмент неисправен. Если бы это было так, мы могли бы, вероятно, сказать такие вещи, как «ключевое слово var считалось вредным», или «резьба считалась вредной». Я думаю, что этот вопрос смущает качество и характер стандарта с трудностями, которые многие программисты используют при правильном использовании и использовании, что я больше чувствую из-за отсутствия понимания того, как работает юникод, а не самого юникода.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
37

В кодировке Utf-16 нет ничего плохого. Но языки, которые рассматривают 16-битные единицы как символы, вероятно, должны считаться плохо спроектированными. Наличие типа с именем char ', который не всегда представляет символ, довольно запутан. Поскольку большинство разработчиков ожидают, что тип символа будет представлять собой кодовую точку или символ, много кода, вероятно, сломается при воздействии на символы BMP.

Обратите внимание, что даже использование utf-32 не означает, что каждая 32-битная точка кода всегда будет представлять символ. Благодаря объединению символов фактический символ может состоять из нескольких кодовых точек. Unicode никогда не бывает тривиальным.

BTW. Вероятно, есть один и тот же класс ошибок с платформами и приложениями, которые ожидают, что символы будут 8-битными, которые передаются Utf-8.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
20

Мой личный выбор - всегда использовать UTF-8. Это стандарт для Linux почти для всех. Он обратно совместим со многими устаревшими приложениями. Существует очень минимальные накладные расходы с точки зрения дополнительного пространства, используемого для нелатинских символов и других форматов UTF, а также значительная экономия пространства для латинских символов. В Интернете господствуют латинские языки, и я думаю, что они будут в обозримом будущем. И для решения одного из главных аргументов в исходном сообщении: почти каждый программист знает, что UTF-8 иногда будет содержать многобайтовые символы. Не все имеют дело с этим правильно, но они, как правило, знают, что больше, чем можно сказать для UTF-16. Но, конечно, вам нужно выбрать наиболее подходящий для вашего приложения. Вот почему в первую очередь есть нечто большее.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
18

Ну, есть кодировка, в которой используются символы фиксированного размера. Я, конечно, имею в виду UTF-32. Но 4 байта для каждого символа - это too большая часть потерянного пространства, почему мы будем использовать его в повседневных ситуациях?

На мой взгляд, большинство проблем возникает из-за того, что какое-то программное обеспечение отстает от стандарта Unicode, но не быстро исправить ситуацию. Opera, Windows, Python, Qt - все они появились до того, как UTF-16 стал широко известен или даже появился. Я могу подтвердить, однако, что в Opera, Windows Explorer и Notepad больше нет проблем с персонажами вне BMP (по крайней мере, на моем ПК). Но в любом случае, если программы не распознают суррогатные пары, то они не используют UTF-16. Какие бы проблемы ни возникали при работе с такими программами, они не имеют никакого отношения к самому UTF-16.

Однако, я думаю, что проблемы с устаревшим программным обеспечением с поддержкой только BMP несколько преувеличены. Символы вне BMP встречаются только в очень специфических случаях и областях. В соответствии с официальным часто задаваемым вопросом Unicode "даже в восточноазиатском тексте, частота суррогатных пар должна быть значительно меньше 1% от всего объема хранения текста в среднем ». Разумеется, символами вне BMP не следует пренебрегать , потому что программа не соответствует Unicode в противном случае, но большинство программ не предназначены для работы с текстами, содержащими такие символы. Вот почему, если они не поддерживают его, это неприятно, но не катастрофа.

Теперь рассмотрим альтернативу. Если UTF-16 не существовал, то у нас не было бы кодирования, которое хорошо подходит для текста, отличного от ASCII, и все программное обеспечение, созданное для UCS-2, должно быть полностью переработано, чтобы оставаться совместимым с Unicode. Последнее, скорее всего, только замедлит принятие Unicode. Также мы не смогли бы поддерживать совместимость с текстом в UCS-2, как UTF-8, в отношении ASCII.

Теперь, отложив в сторону все устаревшие проблемы, каковы аргументы против самой кодировки? Я действительно сомневаюсь, что разработчики в настоящее время не знают, что UTF-16 - это переменная длина, она написана повсюду, набирая Википедию. UTF-16 гораздо труднее разобрать, чем UTF-8, если кто-то указал на сложность как на возможную проблему. Также неверно думать, что легко справиться с определением длины строки только в UTF-16. Если вы используете UTF-8 или UTF-32, вы все равно должны знать, что одна кодовая точка Unicode не обязательно означает один символ. Кроме этого, я не думаю, что есть что-то существенное против кодировки.

Поэтому я не думаю, что сама кодировка должна считаться вредной. UTF-16 - это компромисс между простотой и компактностью, и нет вреда в , используя то, что необходимо там, где это необходимо . В некоторых случаях вам необходимо поддерживать совместимость с ASCII, и вам нужно UTF-8, в некоторых случаях вы хотите работать с идеями Han и сохранять пространство с использованием UTF-16, в некоторых случаях вам нужны универсальные представления символов, длина кодирования. Используйте то, что более уместно, просто сделайте это правильно.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
16

Годы работы по интернационализации Windows, особенно на восточноазиатских языках, могли испортить меня, но я склоняюсь к UTF-16 для внутренних-программных представлений строк, а UTF-8 для сетевого или файлового хранилища с открытым текстом документы. UTF-16, как правило, быстрее обрабатывается в Windows, поэтому это основное преимущество использования UTF-16 в Windows.

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

Конечно, это примерно так же быстро и правильно кодируется UTF-8. Но есть также много сломанных приложений UTF-8, которые неправильно кодируют суррогатные пары в виде двух последовательностей UTF-8. Таким образом, UTF-8 также не гарантирует спасение.

IE обрабатывает суррогатные пары достаточно хорошо с 2000 года или около того, хотя обычно он преобразует их из страниц UTF-8 в внутреннее представление UTF-16; Я уверен, что Firefox тоже прав, поэтому мне все равно, что делает Opera.

UTF-32 (aka UCS4) бессмыслен для большинства приложений, так как он настолько требует пространства, поэтому он почти не запускается.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
16

UTF-8 - это, безусловно, путь, возможно, сопровождаемый UTF-32 для внутреннего использования в алгоритмах, которым необходим высокопроизводительный произвольный доступ (но это игнорирует объединение символов).

Как UTF-16, так и UTF-32 (а также их варианты LE /BE) страдают от проблем с энзиматией, поэтому они никогда не должны использоваться снаружи.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
15

UTF-16? определенно вредно. Просто мое зерно соли здесь, но есть всего три приемлемых кодировки для текста в программе:

  • ASCII: при работе с низкоуровневыми вещами (например, микроконтроллерами), которые не могут позволить себе что-нибудь лучше
  • UTF8: хранение в носителях с фиксированной шириной, таких как файлы
  • целые кодовые точки ("CP"?): массив наибольших целых чисел, которые удобны для вашего языка программирования и платформы (распадается на ASCII в пределе низких resorces). Должен быть int32 на старых компьютерах и int64 на любом с 64-битным адресации.

  • Очевидно, что интерфейсы с устаревшим кодом используют кодировку, необходимую для создания старого права на работу кода.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
13

Unicode определяет коды с точностью до 0x10FFFF (1,114,112 кодов), все приложения, работающие в многоязычной среде, имеющие дело с именами строк /файлов и т. д., должны обращаться с этим правильно.

Utf-16 : охватывает только 1,112,064 кода. Хотя те, что находятся в конце Unicode , относятся к плоскостям 15-16 (частная область использования). Он не может расти дальше в будущем, кроме того, что нарушает концепцию Utf-16 .

Utf-8 : теоретически охватывает 2 216 757 376 кодов. Текущий диапазон кодов Unicode может быть представлен максимально 4 байтовой последовательностью. Он не страдает проблемой байтового порядка , он «совместим» с ascii.

Utf-32 : теоретически охватывает 2 ^ 32 = 4 294 967 296 кодов. В настоящее время он не кодируется переменной длиной и, вероятно, не будет в будущем.

Эти факты самоочевидны. Я не понимаю отстаивания общего использования Utf-16 . Он кодируется с переменной длиной (к нему нельзя получить доступ по индексу), он имеет проблемы для охвата всего диапазона Unicode даже в настоящее время, порядок байтов должен быть обработан и т. Д. Я не вижу никаких преимуществ, кроме того, что это изначально используется в Windows и некоторых других местах. Несмотря на то, что при написании многоплатформенного кода, вероятно, лучше использовать Utf-8 изначально и сделать преобразования только в конечных точках зависимого от платформы способа (как уже было предложено). Если необходим прямой доступ по индексу, а память не является проблемой, следует использовать Utf-32 .

Основная проблема заключается в том, что многие программисты, работающие с Windows Unicode = Utf-16 , даже не знают и не игнорируют тот факт, что он кодируется переменной длиной.

Как правило, платформа * nix довольно хороша, c строки (char *) интерпретируются как Utf-8 , с широкими c-строками (wchar_t *) интерпретируется как Utf-32 .

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
11

Добавьте это в список:

  

Представленный сценарий прост (еще более простой, как я покажу   это здесь, чем было изначально!):    1.A WinForms TextBox находится на форме, пустой. Он имеет значение MaxLength для 20 .

     

2. Пользователь вводит текст в TextBox или может вставлять в него текст.

     

3. Неважно, что вы набираете или вставляете в TextBox, вы ограничены 20, хотя он будет сочувственно звучать в тексте за пределами 20 (YMMV   Вот; Я изменил свою звуковую схему, чтобы дать мне этот эффект!).

     

4. Небольшой пакет текста затем отправляется куда-то еще, чтобы начать захватывающее приключение.

     

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

     

Я даже назвал    Magic Carpet Ride , чтобы облегчить скуку.

     

Это не   работать, для чего это стоит.

     

Поэтому вместо этого я ввел следующие 20   персонажей в мою Магическую ковровую прогулку :

     

0123401234012340123

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
9

Я бы не сказал, что UTF-16 вреден. Он не изящный, но он служит для обратной совместимости с UCS-2, как и GB18030 с GB2312, а UTF-8 - с ASCII.

Но внесение фундаментальных изменений в структуру Unicode в середине потока, после того, как Microsoft и Sun создали огромные API-интерфейсы вокруг 16-разрядных символов, были вредны. Невозможность распространения информации об изменениях была более вредной.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
6

UTF-16 - это лучший компромисс между обработкой и space , поэтому большинство основных платформ (Win32, Java, .NET) используют его для внутреннего представления строк.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
6

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

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
6

Поскольку я еще не могу прокомментировать, я отправляю это как ответ, так как кажется, что я не могу обратиться к авторам utf8everywhere.org. Жаль, что я автоматически не получаю привилегии комментария, так как у меня достаточно репутации на других stackexchanges.

Это подразумевается как комментарий к Мнение: Да, UTF-16 следует считать вредным ответом.

Одна небольшая коррекция:

Чтобы предотвратить случайное прохождение UTF-8 char* в ANSI-строковые версии функций Windows-API, следует определить UNICODE, а не _UNICODE. _UNICODE отображает функции типа _tcslen на wcslen, а не MessageBox на MessageBoxW). Вместо этого параметр UNICODE определяет последний. Для доказательства это из заголовка WinUser.h от MS Visual Studio 2005:

#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

Как минимум, эту ошибку следует исправить на utf8everywhere.org.

Предложение:

Возможно, руководство должно содержать пример явного использования широкоформатной версии структуры данных, чтобы было проще пропустить ее /забыть. Использование широкоформатных версий структур данных поверх широкоформатных версий функций делает еще менее вероятным, что случайно вызывает версию такой функции ANSI.

Пример примера:

WIN32_FIND_DATAW data; // Note the W at the end.
HANDLE hSearch = FindFirstFileW(widen("*.txt").c_str(), &data);
if (hSearch != INVALID_HANDLE_VALUE)
{
    FindClose(hSearch);
    MessageBoxW(nullptr, data.cFileName, nullptr, MB_OK);
}
ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
5

Кто-то сказал, что UCS4 и UTF-32 были такими же. Нет, но я знаю, что вы имеете в виду. Один из них - это кодирование другого. Хотелось бы, чтобы они подумали указать сущность с первого, так что у нас не было бы сражения с энтиансой. Разве они не могли увидеть это? По крайней мере, UTF-8 везде одинаково (если только кто-то не выполняет исходную спецификацию с 6 байтами).

Если вы используете UTF-16, у вас есть , чтобы включить обработку для многобайтовых символов. Вы не можете перейти к символу N, индексируя 2N в массив байтов. Вы должны пройти его или иметь персональные индексы. В противном случае вы написали ошибку.

В текущем черновом проекте C ++ говорится, что UTF-32 и UTF-16 могут иметь мало-endian, big-endian и неуказанные варианты. В самом деле? Если бы Юникод указал, что каждый должен был сделать little-endian с самого начала, тогда все было бы проще. (Я тоже был бы в восторге от big-endian.) Вместо этого некоторые люди реализовали это в одну сторону, а другую, и теперь мы застряли без глупости. Иногда стыдно быть инженером-программистом.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
2

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

Являясь японским разработчиком программного обеспечения, я считаю, что UCS-2 достаточно большой, и ограничение пространства, по-видимому, упрощает логику и сокращает память во время работы, поэтому использование utf-16 в рамках ограничения UCS-2 достаточно хорошо.

Существует файловая система или другое приложение, которое предполагает, что кодовые точки и байты должны быть пропорциональными, чтобы гарантировать, что необработанный номер кодового номера может быть помещен в какое-то фиксированное хранилище.

Одним из примеров является NTFS и VFAT, определяющие UCS-2 как их кодирование хранения имени файла.

Если этот пример действительно хочет распространяться на поддержку UCS-4, я мог бы согласиться с использованием utf-8 для всех в любом случае, но фиксированная длина имеет хорошие точки, такие как:

  1. может гарантировать размер по длине (размер данных и длина кодового слова пропорциональны)
  2. может использовать номер кодировки для поиска хэша
  3. несжатые данные имеют разумный размер (по сравнению с utf-32 /UCS-4)

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

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49
1
  

«Должно ли считаться вредным один из самых популярных кодировок UTF-16?

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

Основная проблема заключается в том, что существует много разных концепций о: глифах, символах, кодовых точках и байтовых последовательностях. Отображение между каждым из них является нетривиальным, даже с помощью библиотеки нормализации. (Например, некоторые символы на европейских языках, написанные латинским сценарием, не написаны с одним кодовым кодом Unicode, а это на более простом конце сложности!) Это означает, что получить все правильное довольно удивительно сложно; Ожидаются жуткие ошибки (и вместо того, чтобы просто стонать о них здесь, сообщать сопровождающим о соответствующем программном обеспечении).

Единственный способ, с помощью которого UTF-16 можно считать вредным, в отличие от, например, UTF-8, заключается в том, что он имеет другой способ кодирования кодовых точек вне BMP (как пара суррогатов). Если код хочет получить доступ или перебрать по кодовой точке, это означает, что он должен знать о различии. OTOH, это означает, что значительная часть существующего кода, который предполагает «персонажи», всегда может быть вписана в двухбайтовое количество - довольно распространенное, если ошибочное, предположение - может, по крайней мере, продолжать работать, не перестраивая его все. Другими словами, по крайней мере, вы можете видеть те символы, которые не обрабатываются правильно!

Я бы поставил свой вопрос на голову и сказал, что весь проклятый шебанг Юникода должен считаться вредным, и каждый должен использовать 8-битную кодировку, за исключением того, что я видел (за последние 20 лет), где это приводит: ужасное замешательство по различным кодировкам ISO 8859, а также весь набор из них, используемых для кириллицы, и пакет EBCDIC, и ... ну, Unicode для всех его ошибок превосходит это. Если бы это был не такой неприятный компромисс между недоразумениями разных стран.

ответил Alexander Torstling 30 Jpm1000000pmThu, 30 Jan 2014 21:48:49 +040014 2014, 21:48:49

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132