2009-07-19 3 views
4

Мне нужна библиотека файлов io, которая может дать моей программе интерфейс utf-16 (little endian), но может обрабатывать файлы в других кодировках, в основном ascii (только вход), utf-8, utf-16 , utf-32/ucs4, включая как маленькие, так и большие байтовые порядки.C++ unicode-файл io

Осмотрев единственную библиотеку, которую я нашел, это библиотека ICU ustdio.h.

Я попытался, однако, я даже не могу это обработать с помощью очень простой части текста, и на его использовании имеется почти нулевая документация, только справочная страница файла ICU, которая не содержит примеров и очень мало деталей (например, сделав UFILE из существующего FILE, безопасно использовать другие функции, которые принимают FILE *? вместе с несколькими другими ...).

Также идентификатор гораздо скорее C++ библиотека, которая может дать мне широкий поток интерфейс через интерфейс в стиле C ...

std::wstring str = L"Hello World in UTF-16!\nAnother line.\n"; 
UFILE *ufile = u_fopen("out2.txt", "w", 0, "utf-16"); 
u_file_write(str.c_str(), str.size(), ufile); 
u_fclose(ufile); 

выход

Hello World in UTF-16!਍䄀渀漀琀栀攀爀 氀椀渀攀⸀ഀ 

шестигранной

FF FE 48 00 65 00 6C 00 6C 00 6F 00 20 00 57 00 
6F 00 72 00 6C 00 64 00 20 00 69 00 6E 00 20 00 
55 00 54 00 46 00 2D 00 31 00 36 00 21 00 0D 0A 
00 41 00 6E 00 6F 00 74 00 68 00 65 00 72 00 20 
00 6C 00 69 00 6E 00 65 00 2E 00 0D 0A 00 

EDIT: правильный вывод на окна будет:

FF FE 48 00 65 00 6C 00 6C 00 6F 00 20 00 57 00 
6F 00 72 00 6C 00 64 00 20 00 69 00 6E 00 20 00 
55 00 54 00 46 00 2D 00 31 00 36 00 21 00 0D 00 
0A 00 41 00 6E 00 6F 00 74 00 68 00 65 00 72 00 
20 00 6C 00 69 00 6E 00 65 00 2E 00 0D 00 0A 00 

ответ

1

Я думаю, что проблемы возникают из-за разломов линии 0D 0A 00. Вы могли бы попробовать, если другие переносами как \r\n или с помощью LF или CR сами по себе работают (лучше всего будет использовать \r, я полагаю)

EDIT: Кажется 0D 00 0A 00 является то, что вы хотите, так что вы можете попробовать

std::wstring str = L"Hello World in UTF-16!\15\12Another line.\15\12"; 
+0

Попробованная такого рода вещи, \ г работ \ п заменяется сломанный \ г \ п, так \ г \ n в моей строке становится 0D 00 0D 0A 00 –

+0

Да, я думал, что это произойдет с \ r \ n. Я даже предполагаю, что 0D 00 0A 00 будет плохим, потому что вы получите две новые линии вместо одной. – schnaader

+0

"(лучше всего будет использовать \ r, я полагаю)" Id скорее использует библиотеку, способную записывать файлы, которые действительны на данной платформе, то есть \ r \ n для dos/windows, \ n для linux и \ r для mac. Помимо одного ar, возможно, будут разбиты многие другие материалы, в которых используются файлы, ожидающие действительных небольших файлов utf-16 с разрывами строк Windows ... –

2

UTF8-CPP дает вам преобразование между UTF-8, 16 и 32. Очень приятная и легкая библиотека.

О ОИТ, некоторые комментарии к UTF8-CPP создатель:

ICU библиотеки. Это очень мощный, полный, многофункциональный, зрелый, и широко используется. Также большой, навязчивый, не общий, и не играет хорошо со стандартной библиотекой. I Определенно рекомендую посмотреть на ICU , даже если вы не планируете его использовать.

:)

4

Проблема, которую вы видите, связана с преобразованием перевода строки. К сожалению, это делается на уровне байта (после преобразования кода) и не знает о кодировке. IOW, вам необходимо отключить автоматическое преобразование (открыв файл в двоичном режиме, с флагом «b»), и, если вы хотите, чтобы 0A00 был расширен до 0D00A00, вам придется сделать это самостоятельно.

Вы сказали, что вы предпочитаете ++ широкий поток интерфейс C, поэтому я опишу то, что я сделал, чтобы добиться того, что в нашей программе:

  • Написать станд :: codecvt огранку, используя ICU UConverter для выполнения преобразований.
  • Используйте зЬй :: wfstream, чтобы открыть файл
  • Заколдованных() своего собственного codecvt в wfstream
  • Откройте wfstream с бинарным флагом, чтобы выключить автоматическое (и ошибочное) перевод строки преобразования.
  • Напишите «WNewlineFilter», чтобы выполнить преобразование строк на wchars. Используйте вдох от boost::iostreams::newline_filter
  • Используйте boost::iostreams::filtering_wstream, чтобы связать wfstream и WNewlineFilter вместе как поток.