winapi — C ++ для чтения и записи файлов UTF-32

Я хочу написать приложение для изучения языка для себя, используя Visual Studio 2017, C ++ и WindowsAPI (ранее известный как Win32). Операционная система является последней инсайдерской сборкой Windows 10, и обратная совместимость не является проблемой. Поскольку я предполагаю, что английский язык является родным языком пользователя, а язык, которым я в данный момент интересуюсь, является еще одним европейским языком, ASCII может быть достаточно. Но я хочу сделать это на будущее (больше экзотических языков), а также хочу попробовать свои силы в UTF-32. Ранее я использовал как UTF-8, так и UTF-16, хотя у меня больше опыта с последующим.

Благодаря std::basic_stringбыло легко понять, как получить строку UTF-32:

typedef std::basic_string<char32_t> stringUTF32

Поскольку я использую WinAPI для всего персонала графического интерфейса, мне нужно сделать некоторое преобразование между UTF-32 и UTF-16.

Теперь о моей проблеме: поскольку UTF-32 не используется широко из-за его неэффективности, в Интернете практически нет материалов об этом. Чтобы избежать ненужных преобразований, я хочу сохранить свои словарные списки и другие данные как UTF-32 (для всех сторонников / евангелистов UTF-8 альтернативой будет UTF-16). Проблема в том, что я не могу найти, как писать и открывать файлы в UTF-32.

Итак, мой вопрос: как писать / открывать файлы в UTF-32? Я бы предпочел, чтобы сторонние библиотеки не требовались, если они не являются частью Windows или обычно поставляются с этой ОС.

1

Решение

Если у тебя есть char32_t последовательность, вы можете записать его в файл, используя std::basic_ofstream<char32_t> (который я буду называть u32_ofstream, но этот typedef не существует). Это работает так же, как std::ofstreamкроме того что пишет char32_tс вместо chars. Но есть ограничения.

Большинство стандартных типов библиотек, которые имеют operator<< Перегрузка зависит от типа символа. Таким образом, они будут работать с u32_ofstream просто хорошо. Проблема, с которой вы столкнетесь, для пользователь типы. Они почти всегда предполагают, что вы пишете charи, таким образом, определяются как ostream &operator<<(ostream &os, ...);, Такой поток вывода не может работать с u32_ofstream без конверсионного слоя.

Но большая проблема, с которой вы столкнетесь, — это проблемы с порядком байтов. u32_ofstream напишет char32_t как родной порядок байтов вашей платформы. Если ваше приложение читает их обратно через u32_ifstream, Все в порядке. Но если другие приложения читают их, или если ваше приложение должно читать что-то, написанное в UTF-32 кем-то другим, это становится проблемой.

Типичным решением является использование «метки порядка байтов» в качестве первого символа файла. Unicode даже имеет определенную кодовую точку, выделенную для этого: \U0000FEFF,

То, как работает спецификация, выглядит следующим образом. При написании файла вы пишете спецификацию перед любыми другими кодовыми точками.

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

constexpr char32_t native_bom = U'\U0000FEFF';

u32_ifstream is(...);
char32_t bom;
is >> bom;
if(native_bom == bom)
{
process_stream(is);
}
else
{
basic_stringstream<char32_t> char_stream
//Load the rest of `is` and endian-convert it into `char_stream`.
process_stream(char_stream);
}
1

Другие решения

Меня сейчас интересует другой европейский язык, поэтому ASCII может быть достаточно

Даже на простом английском. Вы знаете, как Microsoft Word создает «фигурные кавычки»? Это не символы ASCII. Все эти письма с акцентами и умлауты, например. Французский или английский не являются символами ASCII.

Я хочу это на будущее

UTF-8, UTF-16 и UTF-32 могут кодировать каждую кодовую точку Unicode. Они все на будущее. UTF-32 не имеет преимущества перед двумя другими.

Также для проверки в будущем: я уверен, что некоторые сценарии используют символы (технический термин — «кластеры графем»), состоящие из более чем одного кода. Беглый поиск Игра с персонажами деванагари.

Недостатком UTF-32 является поддержка других инструментов. Блокнот не открывает ваши файлы. Вне сравнения не буду. Код Visual Studio… нет. Visual Studio будет, но она не позволит вам создавать такие файлы.

И Win32 API: у него есть функция MultiByteToWideChar который может конвертировать UTF-8 в UTF-16 (который необходимо передать во все вызовы Win32), но он не принимает UTF-32.

Поэтому мой честный ответ на этот вопрос: не. В противном случае следуйте ответу Николь.

1

По вопросам рекламы [email protected]