Если у вас есть последовательность char32_t
, вы можете записать ее в файл, используя std::basic_ofstream<char32_t>
(который я буду называть u32_ofstream
, но этот typedef не существует). Это работает точно так же, как std::ofstream
, за исключением того, что пишет char32_t
с вместо char
с. Но есть ограничения.
Большинство стандартных типов библиотек с перегрузкой operator<<
настроены на тип символа. Так что они будут работать с u32_ofstream
просто отлично. Проблема, с которой вы столкнетесь, относится к типам user . Они почти всегда предполагают, что вы пишете 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);
}