Поддержка Unicode в С++ 0x
Я пытаюсь использовать новые символы Unicode в С++ 0x.
Поэтому я написал пример кода:
#include <fstream>
#include <string>
int main()
{
std::u32string str = U"Hello World";
std::basic_ofstream<char32_t> fout("output.txt");
fout<<str;
return 0;
}
Но после выполнения этой программы я получаю пустой файл output.txt. Так почему он не печатает Hello World?
Также существует ли что-то вроде cout
и cin
для этих типов, или stdin
и stdout
не поддерживает Unicode?
Изменить: я использую g++ и Linux.
EDIT: АТТЕNTION. Я обнаружил, что стандартный комитет отклонил потоки Unicode из С++ 0x. Таким образом, ранее принятый ответ больше не подходит. Для получения дополнительной информации см. мой ответ!
Ответы
Ответ 1
Строковые литералы Unicode поддерживают в GCC 4.5. Может быть, проблема.
[править]
После некоторого копания я обнаружил, что потоки для этих новых литералов в Юникоде описаны в N2035, и это было включен в черновик стандарта. В соответствии с этим документом вам понадобится u32ofstream
для вывода строки, но этот класс отсутствует в библиотеке GCC 4.5 С++ 0x.
В качестве обходного пути вы можете использовать обычный fstream:
std::ofstream fout2("output2.txt", std::ios::out | std::ios::binary);
fout2.write((const char *)str.c_str(), str.size() * 4);
Таким образом, я выводил вашу строку в UTF-32LE на моей машине Intel (что мало-пошло).
[править]
Я немного ошибался в отношении статуса u32ofstream
: согласно последнему проекту в Комитете по стандартам С++ , вы должны использовать std::basic_ofstream<char32_t>
, как и вы. Этот класс использовал бы класс codecvt<char32_t,char,typename traits::state_type>
(см. Конец § 27.9.1.1), который должен быть реализован в стандартной библиотеке (поиск codecvt<char32_t
в документе), но он недоступен в GCC 4.5.
Ответ 2
В новом стандарте С++ не будет потоков Unicode.
Как отметил @ssmir, стандартный комитет собирался добавить поддержку потока для Unicode в С++ 0x. Однако в комитете по функциям редакция решила удалить поддержку потока для Unicode. Для получения дополнительной информации см. Ссылку .
Он выглядит как единственный способ вывода строки Unicode, чтобы преобразовать его в строку ASCII с codecvt.
Ответ 3
При создании поток пытается получить "codecvt" из глобальной локали, но не получает его, потому что единственный стандартный codecvt для char и wchar_t.
В результате член _M_codecvt объекта потока имеет значение NULL.
Позже, во время попытки вывода, ваш код генерирует исключение (не видимое пользователю) в функции проверки грани в basic_ios.h, потому что фасет инициализирован из _M_codecvt.
Добавить фасет в локальный, связанный с потоком, для преобразования из char32_t в правильный вывод.
Настройте поток локалью, содержащей кодек нужного типа.