Поддержка C ++ UTF-8 в Unix / Mac OS X - PullRequest
1 голос
/ 14 марта 2011

Мне нужен способ, чтобы иметь возможность читать из файла в кодировке UTF-8 и сохранять данные из него в «UTF-8-совместимые строки» некоторого вида, в C ++.Эти данные необходимо записать обратно в файл в кодировке UTF-8 позже.Похоже, в Google есть много советов о том, как сделать это в Windows, но я не могу найти никакой помощи для систем Unix.

Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 14 марта 2011

Если все, что вам нужно сделать, это прочитать и записать его, тогда std :: string вполне подойдет.

std::ifstream    fileIn("file.utf8");

std::string   line;
std::getline(fileIn, line); // Reads a UTF-8 line

std::ofstream    fileOut("OutFile.utf8");
fileOut << line; // Writes a line of UTF-8 text

Это работает, потому что ни одна многосимвольная кодовая точка UTF не перекрывается с символом ASCII, поэтому стандартная обработкатекста работает просто отлично по отношению к концу строки, и поток не выполняет никакой другой обработки.То, что вы читаете, это то, что вы получаете.Вывод строки не изменяет ни одну из кодовых точек.

Теперь, если вам нужно манипулировать текстом, который представляет собой другой вопрос и становится более сложным.

Обычно манипулирование UTF-8 является сложным(можно сделать но не стоит ИМО).

Когда дело доходит до манипулирования текстом, вы хотите преобразовать UTF-8 (который не является фиксированной шириной) во внутренний формат фиксированной ширины;(UTF-16 или UTF-32 являются распространенными форматами для манипулирования и просты в использовании; (окна UTF-16, UTF-32 для большинства * nix-подобных ОС)).Самый простой способ сделать это - наполнить поток фасетом, который знает, что входные данные находятся в UTF-8, и автоматически преобразует его.

Есть несколько таких фасетов, плавающих в разных библиотеках.Но легко найти это повышение:

http://www.boost.org/doc/libs/1_38_0/libs/serialization/doc/codecvt.html

Примечание: это также в последней версии повышение 1,46

std::locale old_locale;
std::locale utf8_locale(old_locale,new utf8_codecvt_facet<ucs4_t>);
                              //   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  The important bit
                              //   Note here we are converting to UTF-32(UCS-4)

std::wifstream fileIn;
fileIn.imbue(utf8_locale);    // Imbue the stream with the knowledge.

fileIn.open("file.utf8");
// Now read wide characters from the stream. The UTF-8 file is converted 
// into UTF-16/UTF-32 for internal processing.

std::wstring    wideLine;
std::getline(fileIn, wideLine); // Read a line converting to UTF-16/32

Процессы одинаковы для записи UTF-16/32 обратно в поток и преобразования его в UTF-8

std::wofstream fileOut;
fileOut.imbue(utf8_locale);

fileOut.open("OutFile.utf8");
fileOut << wideLine;      // Write a UTF-16/32 line and convert into UTF-8

Примечание.Вы должны наполнить файл до его открытия.Различные реализации потока будут реагировать по-разному, если вы наполняете поток после его открытия.Таким образом, лучше всего наполнить поток перед его открытием.

Dinkumware также имеет набор конверсионных граней (не уверен, что они свободны).
http://www.dinkumware.com/manuals/default.aspx?manual=compleat&page=index_cvt.html#Code%20Conversions

Примечание: Iпредпочитаю использовать термины UTF-X, а не UCS-Y.Хотя технически есть очень незначительные различия, они несущественны по сравнению с путаницей, которую вы можете создать, переключаясь между двумя терминами, когда говорите о предмете.Придерживайтесь одного, если вам не нужно явно говорить о функции (например, суррогатных пар).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...