Re[4]: тысяча третий раз про Юникод
От: pepsicoca  
Дата: 14.10.09 12:31
Оценка:
Здравствуйте, Rakafon, Вы писали:

R>Здравствуйте, pepsicoca, Вы писали:


P>>Зная, что терминал не юникодный и зная, что нужно выводить кириллицу (это можно узнать из Юникодного кода кирилических символов) почему бы системе самой перед выводом кирилицы не сделать imbue той локали, которая нужна?


R>Вы думаете щазз здесь появится разработчики виндовой консоли и разраюботчики std::cout/std::wcout из мелкософта и начнуть объяснять технически детали и причины нереализации таковой фичи.


Ну не до такой же степени. Вдумайтесь — Юникод специально был создан, чтобы не переключать локали. И вот после всего этого, чтобы вывести Юникодный символ нужно явно указать локаль? Зачем тогда Юникод было городить?

R>Я ж говорю: виндовая консоль — гавно! Сделайте свою консоль с нативной поддержкой Unicod'а и возможностью писать шрифтом "Georgia", "Gigi" или "Kunstler Script", и будет вам счастье!


P>>Этот пример печатает в файл только латинское hello. Причем не в Юникоде, а в ASCII.


R>А собственно что Вас удивляет/огорчает? Это стандартное поведение: так и должно быть. Как я Вам уже писал здесь: <span class='lineQuote level1'>R&gt;forum/cpp/3567835.1.aspx</span>
Автор: Rakafon
Дата: 13.10.09
, (кстати совсем непонятно, зачем вы создали новую тему? это такая спамерская черта характера?)


Там уже никто не читает.

R>так вот, как я Вам уже писал, реализаций Unicod'а есть масса, соответственно std::ifstream/std::ofstream понятия не имеет в какой именно из Unicode кодировок представлен файл, поэтому файл всегда рассматривается как последовательность байт, т.е. "char".


Это верно для std::ofstream. Для std::wofstream ожидаемое поведение не такое. Очевидно, что если std::ofstream работает с файлом как с последовательностью байт char, то std::wofstream должен работать с файлом как с последовательностью широких байт wchar_t.

R>Таковое поведение стандартно, и иначе и быть не может. И конечно, по умолчанию, в качестве кодировки для char* в файле используется ASCII. Для выполнения конвертации из файлового представления в представление в памяти (т.е. из char в wchar_t и наоборот) необходимо использовать специальные объекты — facet'ы. Как это делать, смотрите здесь: Standard file streams and std::locale.и здесь: How to read unicode text file in C++.


R>Если использование boost'овских facet'ов или написание своих facet'ов вам совсем не улыбается, или если задача является более сложной, чем просто конвертнуть ASCII в UTF-16, тогда работу с Unicode файлами всегда можно делать руками: ну например вы имеете файл, и вы знаете, что он закодирован в Unicode кодировке UTF-8, а вам надо его отобразить в некой системе работающей только с UTF-16 (ну скажем, передать текст в функцию, принимающую UTF-16 текст как аргумент wchar_t*), тогда вы, например используя библиотеку iconv, вычитываете файл, закодированный в кодировке UTF-8 в буффер char* B1, создаёте буфер char* B2 с достаточной ёмкостью, кодируете текст из UTF-8 в UTF-16 используя функции библиотеки iconv, затем получаете указатель wchar_t* wB2 = reinterpret_cast<wchar_t*>(B2), который уже отдаёте функции, принимающей UTF-16 текст как аргумент wchar_t*.

R>Опять же, если у Вас есть задача сохранить файл в Unicode, тогда необходимо уточнить требование: в какой именно из Unicode кодировок его сохранить, и, исходя из source данных выбрать алгоритм коныертации, конвертнуть и сохранить. На MS Windows для кодирования текста можно воспользоваться функциями MultiByteToWideChar/WideCharToMultiByte, однако библиотека iconv предоставляет более богатые возможности для кодирования текста.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.