Выход С++ UTF-8 с ICU
Я изо всех сил пытаюсь начать работу с библиотекой ICU С++. Я попытался заставить простейший пример работать, но даже это провалилось. Я просто хотел бы выводить строку UTF-8, а затем перейти оттуда.
Вот что у меня есть:
#include <unicode/unistr.h>
#include <unicode/ustream.h>
#include <iostream>
int main()
{
UnicodeString s = UNICODE_STRING_SIMPLE("привет");
std::cout << s << std::endl;
return 0;
}
Вот результат:
$ g++ -I/sw/include -licucore -Wall -Werror -o icu_test main.cpp
$ ./icu_test
пÑивеÑ
Мой терминал и поддержка шрифтов UTF-8 и я регулярно использую терминал с UTF-8. Мой исходный код находится в UTF-8.
Я думаю, что, возможно, мне нужно установить выходной поток в UTF-8, потому что ICU хранит строки как UTF-16, но я действительно не уверен, и я бы подумал, что операторы, предоставленные ustream.h, будут делать в любом случае.
Любая помощь будет оценена, спасибо.
Ответы
Ответ 1
Ваша программа будет работать, если вы просто измените инициализатор на:
UnicodeString s("привет");
Макрос, который вы использовали, только для строк, содержащих "инвариантные символы" , т.е. только латинские буквы, цифры и некоторую пунктуацию.
Как уже было сказано, кодовые страницы ввода/вывода сложны. Вы сказали:
Мой терминал и поддержка шрифтов UTF-8 и Я регулярно использую терминал с UTF-8. Мой исходный код находится в UTF-8.
Это может быть правдой, но ICU не знает этого. Кодовая страница процесса может отличаться (например, iso-8859-1), а выходная кодовая страница может быть разной (скажем, shift-jis). Тогда программа не сработает. Но инвариантные символы, использующие API UNICODE_STRING_SIMPLE, все равно будут работать.
Надеюсь, что это поможет.
srl, icu dev
Ответ 2
Что произойдет, если вы напишете вывод в файл (либо перенаправляете с помощью труб из терминала, либо открываете поток файлов в самой программе)
Это будет определять, не является ли это терминалом, который не смог правильно обработать вывод.
Что произойдет, если вы проверите выходную строку в отладчике? Он содержит правильные значения? Узнайте, что должно выглядеть кодировка UTF-8 вашей строки, и сравните ее с тем, что вы получаете в отладчике. Или распечатайте интегральное значение каждого байта и убедитесь, что они верны.
При работе с кодировкой всегда сложно (но важно) определить, находится ли проблема в самой программе или в преобразовании, которое происходит, когда текст выводится в систему. Выньте терминал из уравнения и убедитесь, что ваша программа генерирует правильный вывод.
Ответ 3
operator<<(ostream, UnicodeString)
преобразует между UTF16 и символами с помощью конвертера по умолчанию ICU. AFAIU, "конвертер по умолчанию" (если вы не устанавливаете его явно с помощью ucnv_setDefaultName()
), зависит от платформы и способа компиляции ICU. Что вы получаете от ucnv_getDefaultName()
?