Чтение файлов в кодировке utf8 (linux+C++)
От: Vostok Россия  
Дата: 18.08.09 10:30
Оценка:
Решил озадачится этим вопросом. Прочитал с форумов rsdn про фасеты, решил использовать из набора boost: utf8_codecvt_facet. Чтение решил выполнить по алгоритму:

http://www.gamedev.ru/code/forum/?id=73328 — 4-ый комментарий.

Соответственно вопрос: Как же скомпилить нормально тест? Компиляция проваливается так:
g++ test.cpp -o test.exe
/home/vostok/tmp/ccfvenOQ.o: In function `boost::archive::detail::utf8_codecvt_facet::utf8_codecvt_facet(unsigned int)':
test.cpp.text._ZN5boost7archive6detail18utf8_codecvt_facetC1Ej[boost::archive::detail::utf8_codecvt_facet::utf8_codecvt_facet(unsigned int)]+0x19): undefined reference to `vtable for boost::archive::detail::utf8_codecvt_facet'
collect2: ld returned 1 exit status

При этом:

$ g++ --version
i586-alt-linux-g++ (GCC) 4.1.2 20070626 (ALT Linux, build 4.1.2-alt5)

Текст теста:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <iterator>

using namespace std;

#include <boost/archive/detail/utf8_codecvt_facet.hpp>
using namespace boost;


int main()
{
wifstream fIn;
fIn.open("l2");
locale old_locale;
locale utf8_locale(old_locale, new archive::detail::utf8_codecvt_facet);
fIn.imbue(utf8_locale);
wstring<--->str;
fIn>>str;
wcout << str;
fIn.close();
return 0;
}

Пробовал ещё
http://chab.royalinfo.ru/how-to-read-unicode-text-file-in-c/

Но там тоже нужно использовать этот хедер.

Заранее благодарен за помощь.
Re: Чтение файлов в кодировке utf8 (linux+C++)
От: Roman Odaisky Украина  
Дата: 18.08.09 10:32
Оценка: -3
Здравствуйте, Vostok, Вы писали:

V>Решил озадачится этим вопросом. Прочитал с форумов rsdn про фасеты, решил использовать из набора boost: utf8_codecvt_facet.


В большинстве случаев UTF-8 можно читать в char и работать так же, как и с ASCII.
До последнего не верил в пирамиду Лебедева.
Re[2]: Чтение файлов в кодировке utf8 (linux+C++)
От: Vostok Россия  
Дата: 18.08.09 10:46
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

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


V>>Решил озадачится этим вопросом. Прочитал с форумов rsdn про фасеты, решил использовать из набора boost: utf8_codecvt_facet.


RO>В большинстве случаев UTF-8 можно читать в char и работать так же, как и с ASCII.


Да, конечно, полностью с вами согласен. Я так сначала и сделал. Но возникла следующая проблема. У меня в файле с кодировкой utf8 (это данность, к сожалению, а может и благо) содержатся английские и русские слова, а так же числа и прочая разнородная информация. Далее я делю файл на лексемы и получаю массивы русских/английских слов. Ну и, естественно, когда я пытаюсь определить длину слов, которые хранятся в виде string, то для русских слов размер, конечно, определяется некорректно. Вот и я решил исправить всё кардинально: читать всё в utf8 в wstring и получать правильные длины слов.
Re: Чтение файлов в кодировке utf8 (linux+C++)
От: Vostok Россия  
Дата: 18.08.09 11:34
Оценка:
Здравствуйте, Vostok, Вы писали:

V>Решил озадачится этим вопросом. Прочитал с форумов rsdn про фасеты, решил использовать из набора boost: utf8_codecvt_facet. Чтение решил выполнить по алгоритму:


V>http://www.gamedev.ru/code/forum/?id=73328 — 4-ый комментарий.


V>Соответственно вопрос: Как же скомпилить нормально тест? Компиляция проваливается так:

V>g++ test.cpp -o test.exe
V>/home/vostok/tmp/ccfvenOQ.o: In function `boost::archive::detail::utf8_codecvt_facet::utf8_codecvt_facet(unsigned int)':
V>test.cpp:(.text._ZN5boost7archive6detail18utf8_codecvt_facetC1Ej[boost::archive::detail::utf8_codecvt_facet::utf8_codecvt_facet(unsigned int)]+0x19): undefined reference to `vtable for boost::archive::detail::utf8_codecvt_facet'
V>collect2: ld returned 1 exit status

Разобрался с помощью друга:
g++ test.cpp -lboost_wserialization -o test.exe

Но читает/выводит? всё равно неправильно — русские символы выводятся знаками "?" в консоли..
Re: Чтение файлов в кодировке utf8 (linux+C++)
От: zaufi Земля  
Дата: 18.08.09 16:40
Оценка:
альтернативный способ: читать в char* буффер (из обыкновенного ifstream) и потом сконверить его в wcharы с помощью mbstowcs...
Re: Чтение файлов в кодировке utf8 (linux+C++)
От: Ytz https://github.com/mtrempoltsev
Дата: 18.08.09 17:15
Оценка:
Смотрите UTF8-CPP — простая библиотечка, конвертация UTF-8 <-> UTF-16 <-> UTF-32, все удовольствие в трех заголовочных файлах. Принцип следующий — все сохраняем в UTF-8, читаем тоже в UTF-8, внутри программы храним все в UTF-16 или в UTF-32 — зависит от платформы, узнаем по sizeof(wchar_t), используем std::wstring.
Re[2]: Чтение файлов в кодировке utf8 (linux+C++)
От: Ytz https://github.com/mtrempoltsev
Дата: 18.08.09 17:18
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>В большинстве случаев UTF-8 можно читать в char и работать так же, как и с ASCII.


Только с англоязычным текстом.
Re[3]: Чтение файлов в кодировке utf8 (linux+C++)
От: Roman Odaisky Украина  
Дата: 18.08.09 18:01
Оценка:
Здравствуйте, Ytz, Вы писали:

RO>>В большинстве случаев UTF-8 можно читать в char и работать так же, как и с ASCII.

Ytz>Только с англоязычным текстом.

Отнюдь.

До последнего не верил в пирамиду Лебедева.
Re[3]: Чтение файлов в кодировке utf8 (linux+C++)
От: Roman Odaisky Украина  
Дата: 18.08.09 18:23
Оценка:
Здравствуйте, Vostok, Вы писали:

V>Ну и, естественно, когда я пытаюсь определить длину слов, которые хранятся в виде string, то для русских слов размер, конечно, определяется некорректно. Вот и я решил исправить всё кардинально: читать всё в utf8 в wstring и получать правильные длины слов.


Не получишь ты правильные длины слов подсчетом количества Unicode code points.

Café (U+0043 U+0061 U+0066 U+00E9) — сколько букв? (Правильный ответ: 4.)
Café (U+0043 U+0061 U+0066 U+0065 U+0301) — сколько букв? (Правильный ответ: 4.)

Shuffle (U+0053 U+0068 U+0075 U+0066 U+0066 U+006C U+0065) — сколько букв? (Правильный ответ: 7.)
Shuffle (U+0053 U+0068 U+0075 U+FB04 U+0065) — сколько букв? (Правильный ответ: 7.)

Encyclopædia (U+0045 U+006E U+0063 U+0079 U+0063 U+006C U+006F U+0070 U+00E6 U+0064 U+0069 U+0061) — сколько букв? (Правильный ответ: 13.)

Ударе́ние (U+0423 U+0434 U+0430 U+0440 U+0435 U+0301 U+043D U+0438 U+0435) — сколько букв? (Правильный ответ: 8.)

(В шрифте Verdana диакритические знаки сползают)
До последнего не верил в пирамиду Лебедева.
Re[4]: Чтение файлов в кодировке utf8 (linux+C++)
От: Ytz https://github.com/mtrempoltsev
Дата: 18.08.09 18:28
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

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


RO>>>В большинстве случаев UTF-8 можно читать в char и работать так же, как и с ASCII.

Ytz>>Только с англоязычным текстом.

RO>Отнюдь.


Помимо того, что показанное Вами решение не переносимо, так оно еще и не работает так как надо. Например посмотрите, что выдаст s.length()
Re[5]: Чтение файлов в кодировке utf8 (linux+C++)
От: Roman Odaisky Украина  
Дата: 18.08.09 19:31
Оценка:
Здравствуйте, Ytz, Вы писали:

RO>>>>В большинстве случаев UTF-8 можно читать в char и работать так же, как и с ASCII.

Ytz>>>Только с англоязычным текстом.
RO>>Отнюдь.
RO>>http://files.rsdn.ru/48787/washing-windows-4.3.png
Ytz>Помимо того, что показанное Вами решение не переносимо,

Оно непереносимо только в том смысле, что в исходниках на C++ допустимы только символы из ASCII. А читать UTF-8 в char[], обрабатывать и выводить вполне можно.

Ytz>так оно еще и не работает так как надо. Например посмотрите, что выдаст s.length()


Выдаст количество байтов в строке. std::wstring::length выдала бы количество Unicode code points, что было бы не более информативно (ну зачем, зачем считать уникодные символы?!).
До последнего не верил в пирамиду Лебедева.
Re[2]: Чтение файлов в кодировке utf8 (linux+C++)
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 18.08.09 23:25
Оценка:
Для конвертации различных текстовых кодировок всегда использовал библиотеку libiconv: http://www.gnu.org/software/libiconv/.

Здравствуйте, Ytz, Вы писали:
Ytz>Смотрите UTF8-CPP — простая библиотечка, конвертация UTF-8 <-> UTF-16 <-> UTF-32, все удовольствие в трех заголовочных файлах.

Ytz, а можно link на эту библиотечку?
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
iconv charset ansi utf-8 utf-16
Re[4]: Чтение файлов в кодировке utf8 (linux+C++)
От: Vostok Россия  
Дата: 19.08.09 10:31
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

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


V>>Ну и, естественно, когда я пытаюсь определить длину слов, которые хранятся в виде string, то для русских слов размер, конечно, определяется некорректно. Вот и я решил исправить всё кардинально: читать всё в utf8 в wstring и получать правильные длины слов.


RO>Не получишь ты правильные длины слов подсчетом количества Unicode code points.


RO>Café (U+0043 U+0061 U+0066 U+00E9) — сколько букв? (Правильный ответ: 4.)

RO>Café (U+0043 U+0061 U+0066 U+0065 U+0301) — сколько букв? (Правильный ответ: 4.)

RO>Shuffle (U+0053 U+0068 U+0075 U+0066 U+0066 U+006C U+0065) — сколько букв? (Правильный ответ: 7.)

RO>Shuffle (U+0053 U+0068 U+0075 U+FB04 U+0065) — сколько букв? (Правильный ответ: 7.)

RO>Encyclopædia (U+0045 U+006E U+0063 U+0079 U+0063 U+006C U+006F U+0070 U+00E6 U+0064 U+0069 U+0061) — сколько букв? (Правильный ответ: 13.)


RO>Ударе́ние (U+0423 U+0434 U+0430 U+0440 U+0435 U+0301 U+043D U+0438 U+0435) — сколько букв? (Правильный ответ: 8.)


RO>(В шрифте Verdana диакритические знаки сползают)


Хм, а я сделал следующим образом: после курения доков посетила прекрасное знание, что wstring хранит всё в UCS-2. Взял конвертацию UTF-8 -> UCS-2 и длина слов wstring стала считаться верно.. Чего я и добивался.

Но проблему с wcout пока не осилил. Как я понимаю, надо перед выводом всё обратно в utf-8 гнать, либо wcout выставлять ucs-2. Но что-то с наскока не получилось.
Re[2]: Чтение файлов в кодировке utf8 (linux+C++)
От: Vostok Россия  
Дата: 19.08.09 10:32
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>альтернативный способ: читать в char* буффер (из обыкновенного ifstream) и потом сконверить его в wcharы с помощью mbstowcs...

Это второе что я попробовал (после iconv). Результат нулевой.
Re[3]: Чтение файлов в кодировке utf8 (linux+C++)
От: Ytz https://github.com/mtrempoltsev
Дата: 19.08.09 16:32
Оценка:
Здравствуйте, Rakafon, Вы писали:

Ytz>>Смотрите UTF8-CPP — простая библиотечка, конвертация UTF-8 <-> UTF-16 <-> UTF-32, все удовольствие в трех заголовочных файлах.


R>Ytz, а можно link на эту библиотечку?


Пожалуйста http://sourceforge.net/projects/utfcpp/
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.