Вот пример кода, написанного с использованием стандартной библиотеки:
void process_file(const char *filename)
{
std::ifstream f(filename);
std::string s;
while (!f.eof())
{
std::getline(f, s);
process_line(s);
}
f.close();
}
На первый взгляд все замечательно, но только на первый. В реальности и в имени файла, и в самом тексте могут встретиться символы, не входящие в стандартный ASCII алфавит.
А проблема в приведенном фрагменте кода в двух местах:
1. const char *filename
2. std::string s;
С первым разобраться достаточно просто:
void process_file(const wchar_t *filename)
{
std::ifstream f(_wfopen(filename, L"rb"));
...
}
Казалось бы – и второе достаточно просто решается, заменой ifstream на wifstream. Однако, не все так просто как кажется. А загвоздка вот в чем – текстовые файлы в unicode могут быть в различных кодировках: UTF-8, UTF-16, ... Да и в принципе могут встретиться «старые добрые» файлы в ANSI кодировке.
Как и следовало полагать, «велосипед» по чтению unicode-файлов уже давно изобрели. Вообще, я ожидал его увидеть в boost-е, но его там не оказалось. Я нашел его... в contributes к boost-у. Причем эта библиотека датирована 2003 годом, но так и не попала в boost!
Библиотека отлично работает, сама разпознает кодировку по BOM. Самое интересное – в ней сразу нашлась небольшая ошибка:
facet_type* facet;
switch(is.get())
{
case ...:
case ...:
}
if(!facet)
{
...
}
return facet;
Присвоение переменной facet значения идет только в случаях, если выполняется один из case-ов, в любых других случаях она остается неинициализированной, о чем мне и сообщил VC 7.1. Вылечилось просто:
facet_type* facet = NULL;
Использование библиотеки очень простое:
std::wifstream input_file(file_name, std::ios_base::binary);
// autodetect the UTF encoding of this file
boost::utf::imbue_detect_from_bom(input_file);
// some reading
std::wstring s;
input_file >> s;
Только возникают небольшая (легко устранимая) проблема с интерпретацией конца строки в файле, открытом в режиме binary (CR LF уже не становится автоматически LF).
Вызывает сомнения то, что библиотека с 2003 года не обновлялась и так и не включилась в boost, да еще эта ошибка... Поиск в конференциях показал, что используют эту библиотеку очень редко. Значит используют что-то другое? Скорее всего тяжеловесную ICU.
Комментариев нет:
Отправить комментарий