![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Ulysses4j |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 304 Регистрация: 6.6.2007 Где: Ростов-на-Дону Репутация: 4 Всего: 10 |
Извините, что дублирую тему, которая сейчас обсуждается рядом, но как-то она меня не радует, и толькаться не хотелось бы. Дело в том, что волнуют меня близкие вещи к тому, что обсуждается там, но то обсуждение на мой взгляд как-то малоконструктивно, потому я решил задать максимально конкретный, четкий, простой вопрос.
Может кто-нибудь привести работающий пример чтения и вывода на консоль файла в UTF-8 (или любой другой Unicode-кодировки). Вот, что написал я:
Выводит пустую строку. Содержимое файла test.txt в UTF-8, это одна строка в кириллице. -------------------- Communication is critical to the job of a programmer. C. Jazdzewski. Fatherly Advice To New Programmers |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Интересно. На деле с Unicode я работал только средствами Qt, а этот код у меня тоже выводит пустую строку.
Более того, код "f >> s;" вообще генерирует
Возможно, оно хочет BOM в начале файла. Не знаю... |
|||
|
||||
Annihilator |
|
|||
![]() bytegrinder ![]() ![]() Профиль Группа: Участник Сообщений: 493 Регистрация: 21.11.2006 Где: Омск Репутация: 1 Всего: 3 |
может это поможет
-------------------- Если вы не можете сделать хоpошyю пpогpаммy, сделайте, чтобы она по кpайней меpе выглядела хоpошо |
|||
|
||||
Ulysses4j |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 304 Регистрация: 6.6.2007 Где: Ростов-на-Дону Репутация: 4 Всего: 10 |
JackYF, скажу насчет Qt: я искал в сети ответ на свой вопрос, разумеется. Так вот все Unicode-решения на C++ были завязаны на некую библиотеку. Boost предлагает пользоваться поделием от IBM, есть варианты с MFC, ну и Qt, да. Это очень печально, если никак нельзя получить из коробки поддержку таких простейших операций, как ввод-вывод. Стандарт C++ устаревает все сильней.
Annihilator, не устраивает по двум параметрам: 1. C — не люблю этот язык программирования. 2. Привязка к вендору (gcc, glibc). Забавно, что даже учитывая то, что ISO C99 попытался как-то осмысленно подойти к поддержке Unicode, некоторые стандартные строковые функции C остаются неприсобленными к нему. Однако, спасибо за отклик. -------------------- Communication is critical to the job of a programmer. C. Jazdzewski. Fatherly Advice To New Programmers |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Ulysses4j, функция mbstowcs соответствует стандарту C99 и не зависит от библиотек и платформ. Другое дело, что далеко не все производители поддержали этот стандарт.
|
|||
|
||||
Ulysses4j |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 304 Регистрация: 6.6.2007 Где: Ростов-на-Дону Репутация: 4 Всего: 10 |
bsa, она даже соответствует ISO/IEC 9899:1990, но дело в том, что, как я уже говорил, в первую очередь меня не устраивает то, что это C. Я и тему соответствующим образом назвал. Это мне придется, чтобы использовать mb*, открывать файл как FILE*, потом fread какие-нибудь, это по определенным причинам в данном случае недопустимо. Мне хотелось бы решения на C++.
Это сообщение отредактировал(а) Ulysses4j - 8.7.2008, 01:36 -------------------- Communication is critical to the job of a programmer. C. Jazdzewski. Fatherly Advice To New Programmers |
|||
|
||||
Ulysses4j |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 304 Регистрация: 6.6.2007 Где: Ростов-на-Дону Репутация: 4 Всего: 10 |
Собственно, в стандарте C++ сказано, что mbstowcs с сотоварищи включены. И хотя мне нельзя завязываться на C-интерфейсы, я решил в качестве эксперимента попробовать:
Текст программы в UTF-8, соответственно, там же должны быть литералы. Выводятся кракозябры. Я так понимаю, нужно еще иметь представление о локалях. Я с ними плохо дружу. Системная у меня ru_RU.UTF-8 (в частности, это содержимое переменной окружения LANG). -------------------- Communication is critical to the job of a programmer. C. Jazdzewski. Fatherly Advice To New Programmers |
|||
|
||||
Torsten |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 10.6.2008 Где: Pskov Репутация: 3 Всего: 7 |
Ulysses4j,
Причем тут стандарт ? Какая у тебя кодировка в консоли (или куда ты там выводишь) установлена он в той и выводит. В linux все просто. Установи нужную кодировку через контекстное меню (для konsole) и все выведет нормально. Правда исходник нужно поправить, чтобы было нормальный std::string и std::ifstream - тогда все будет нормально. Написать классы для поддержки utf-8, utf-16 и русских кодировок совсем не сложно. Это сообщение отредактировал(а) Torsten - 8.7.2008, 20:54 --------------------
We have no begining, we have no end. We are infinite. |
|||
|
||||
Ulysses4j |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 304 Регистрация: 6.6.2007 Где: Ростов-на-Дону Репутация: 4 Всего: 10 |
При том, что в современных языках, где поддержка Unicode реализована изначально и осмысленно, никаких вопросов не возникает. С этими wchar_t какая-то байда, потому что когда писался Стандарт 98, люди, по всей видимости, во-первых, не воспринимали Unicode достаточно серьезно (не сказать: не понимали достаточно глубоко), во-вторых, у них как обычно, не было времени над этим подумать. Если откроешь страницу TR2, то увидишь, что в первых рядах «желаемых предложений» стоит поддержка Unicode.
Да что ты говоришь, а я-то думал, что он случайным образом кодировку выбирает. У меня GNU/Linux с локалью ru_RU.UTF-8, в консоли (никакая не Konsole, естественно, потому что не KDE), ясное дело, UTF-8.
Не надо меня лечить: или выложи свою реализацию, или скажи почему приведенный мной код не работает. Это сообщение отредактировал(а) Ulysses4j - 8.7.2008, 21:22 -------------------- Communication is critical to the job of a programmer. C. Jazdzewski. Fatherly Advice To New Programmers |
||||
|
|||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Ulysses4j, попробуй добавить setlocale(LC_CTYPE, "") первой строчкой в main()
|
|||
|
||||
Ulysses4j |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 304 Регистрация: 6.6.2007 Где: Ростов-на-Дону Репутация: 4 Всего: 10 |
Спасибо, bsa, заработало. Получается, возвращаясь к первоначальной задаче: прочитать файл в UTF-8 — нужно читать файл в char[] а потом конвертить в wchar_t, а потом уже загонять в wstring. Как-то не по человечески это.
-------------------- Communication is critical to the job of a programmer. C. Jazdzewski. Fatherly Advice To New Programmers |
|||
|
||||
Ulysses4j |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 304 Регистрация: 6.6.2007 Где: Ростов-на-Дону Репутация: 4 Всего: 10 |
Если кому-то интересно, вот что еще удалось разузнать.
wstring можно инициализировать литералами (если исходник в Unicode) вот так:
Далее про чтение файлов. Все сильно зависит от того, какие локали установлены в операционной системе. В никсах можно посмотреть locale -a а в Windows через Панель управления, Региональные и языковые настройки (или как-то так). У меня в никсах есть упоминания только про UTF-8, так что пока я вроде бы научился читать и писать файлы в UTF-8 (соответственно, в UTF-16 не получается):
После этого out.txt содержит:
Строка locale::global(locale("")); была изначально навеяна советом bsa, за что ему еще раз отдельное спасибо и плюс в карму по возможности (если у кого из окружающих есть полномочия). Медитация со стандартом в одной руке и Гуглом в другой привела к следующим фактам: вначале каждой программы, неявно выставляется локаль с особым именем "C", которая существует как бы в любой системе и содержит минимальные сведения для того, чтобы программа на C/C++ могла работать. Этот минимум может совсем не устравать. Первое, что можно сделать это явно попросить взять стандартную системную локаль: как раз вызвав setlocale(LC_ALL, "") (LC_TYPE, как советовал bsa, может хватить для действий со строками, да) и/или locale::global(locale(""));, в зависимости от того, какими средствами собираетесь пользоваться (пустая строка в обоих случаях означает, что настоящее имя системной локали знает система, это как бы конструктор по умолчанию). Ну вот, а что может быть лучше я и не знаю. В принципе, приведенную выше программу можно назвать переносимой в следующем смысле: она будет корректно работать, если файл test.txt находится в кодировке, соответствующей системной локали. Для последних Windows это часто UTF-16. Для интернационализированных никсов это часто UTF-8. Меня сильно волнуют вопросы переносимости, так что если кто-то поиграется с этим под виндами или просто сможет высказать какие-то ценные мысли в этом русле, буду признателен. Такие дела. Всем спасибо за участие. Это сообщение отредактировал(а) Ulysses4j - 9.7.2008, 02:04 -------------------- Communication is critical to the job of a programmer. C. Jazdzewski. Fatherly Advice To New Programmers |
||||||
|
|||||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
||||
|
||||
Ulysses4j |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 304 Регистрация: 6.6.2007 Где: Ростов-на-Дону Репутация: 4 Всего: 10 |
Под Windows не получается выставить локаль, которая бы распознавала UTF-*, не знаю, какое у нее должно быть имя, пробовал разные варианты, гуглил — все попусту. У системной: «Russian_Russia.CP1251», соответственно, понимает только однобайтовую cp1251.
-------------------- Communication is critical to the job of a programmer. C. Jazdzewski. Fatherly Advice To New Programmers |
|||
|
||||
NovorosSupport |
|
||||
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 15.7.2009 Репутация: нет Всего: нет |
Инструкция setlocale(LC_ALL,"Russian"); возвращает в моём и, очевидно, в твоём случае "Russian_Russia.1251" ![]() Хотя мне проще запомнить и использовать setlocale(LC_ALL, ".1251" );
После указания конкретной кодовой страницы инструкцией setlocale(LC_ALL, ".1251" ) ничего этого уже не понадобилось. Файл с кириллицей корректно считывался в объект string и затем корректно выводился в cout! Причем в моём случае даже wcout стал не нужным. подробнее о команде и её параметрах можно почитать здесь |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |