Как работать с UTF-8 на C++, преобразование из других кодировок в UTF-8
Я не знаю, как решить, что:
представьте, у нас есть 4 веб-сайта:
- A: UTF-8
- B: ISO-8859-1
- C: ASCII
- D: UTF-16
моя программа, написанная на C++, делает следующее: она загружает веб-сайт и анализирует его. Но он должен понять содержание. Моя проблема не в разборе, который выполняется с ASCII-символами, такими как ">"
или "<"
.
проблема в том, что программа должна найти все слова из текста сайта. Слово-это любое сочетание буквенно-цифровых символов. Затем я отправляю эти слова на сервер. База данных и веб-интерфейс используют UTF-8. Поэтому мои вопросы:
- как преобразовать" любую " (или наиболее используемую) кодировку символов в UTF-8?
- как я могу работать с UTF-8-строками на C++? Я думаю
wchar_t
не работает, потому что это 2 байта. Код-очков в UTF-8 до 4 байт длинный... - есть ли такие функции, как
isspace()
,isalnum()
,strlen()
,tolower()
для таких UTF-8-строк?
обратите внимание: я не делаю никаких выходных данных (например,std::cout
) в C++. Просто отфильтруйте слова и отправьте их на сервер.
Я знаю о UTF8-CPP, но у него нет is*()
функции. И, как я читал, он не преобразуется из других кодировок символов в UTF-8. Только от UTF - * до UTF-8.
Edit: я забыл сказать, что программа должна будьте портативны: Windows, Linux, ...
4 ответов
как преобразовать" любую " (или наиболее используемую) кодировку символов в UTF-8?
ICU (международные компоненты для Unicode) - это решение здесь. Обычно считается, что это последнее слово в поддержке Unicode. Даже Подталкивание.Язык и создайте.Regex использует его, когда дело доходит до Unicode. См. мой комментарий к ответу Дори Зидона о том, почему я рекомендую использовать ICU напрямую, а не обертки (например, Boost).
вы создаете конвертер для данного кодирование...
#include <ucnv.h>
UConverter * converter;
UErrorCode err = U_ZERO_ERROR;
converter = ucnv_open( "8859-1", &err );
if ( U_SUCCESS( error ) )
{
// ...
ucnv_close( converter );
}
...а затем используйте UnicodeString класс, как appripriate.
Я думаю, что wchar_t не работает, потому что он имеет длину 2 байта.
размер wchar_t
реализация-определено. AFAICR, Windows - 2 байта (UCS-2 / UTF-16, в зависимости от версии Windows), Linux-4 байта (UTF-32). В любом случае, поскольку стандарт не определение семантика Unicode для wchar_t
, используя это непереносимо догадки. Не Угадай, используй интенсивную терапию.
есть такие функции, как является пространство(), айсалкым(), функция strlen(), нижестоящим() Для такие как UTF-8-строк?
не в их кодировке UTF-8, но вы все равно не используете это внутри. UTF-8 хорош для внешнего представления, но внутренне UTF-16 или UTF-32 лучший выбор. Вышеупомянутые функции существуют для кодовых точек Unicode (т. е. UChar32); ref. Учар.h.
Пожалуйста, обратите внимание: Я не делаю никаких выходных данных (например, std::cout) на C++. Просто отфильтруйте слова и отправьте их на сервер.
Регистрация BreakIterator.
Edit: я забыл сказать, что программа должна быть портативной: Windows, Linux,...
если я еще не сказал этого,do используйте ICU,и сохраньте тонны тревоги. Даже если это может показаться немного тяжеловесным на первый взгляд, это is лучшие реализация там, это is чрезвычайно портативный (используя его на Windows, Linux и AIX сам), и вы будет используйте его снова и снова и снова в будущих проектах, поэтому время, вложенное в изучение его API, не тратится впустую.
не уверен, что это даст вам все, что вы ищете, но это может немного помочь. Вы пробовали смотреть на:
1) импульс.Библиотека язык ? Повышение.Locale был выпущен в Boost 1.48 (ноябрь 15th, 2011), что упрощает преобразование из и в UTF8/16
вот несколько удобных примеров из документов:
string utf8_string = to_utf<char>(latin1_string,"Latin1");
wstring wide_string = to_utf<wchar_t>(latin1_string,"Latin1");
string latin1_string = from_utf(wide_string,"Latin1");
string utf8_string2 = utf_to_utf<char>(wide_string);
2) или в преобразования являются частью C++11?
#include <codecvt>
#include <locale>
#include <string>
#include <cassert>
int main() {
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
std::string utf8 = convert.to_bytes(0x5e9);
assert(utf8.length() == 2);
assert(utf8[0] == '\xD7');
assert(utf8[1] == '\xA9');
}
как я могу работать с UTF-8-строками на C++? Я думаю, что wchar_t не работе, потому что это 2 байта. Кодовые точки в UTF-8 до 4 байт...
это легко, есть проект под названием tinyutf8 , который является drop-in замена на std::string
/std::wstring
.
после этого потребитель может шикарно работать дальше коды, в то время как их представление всегда закодированы в char
s.
как преобразовать" любую " (или наиболее используемую) кодировку символов в UTF-8?
возможно, вы захотите взглянуть на std::codecvt_utf8
и simlilar шаблоны С <codecvt>
(C++11).
UTF-8-это кодировка, которая использует несколько байтов для не-ASCII (7-битный код), используя 8-й бит. Как таковой вы не найдете '\'
, '/'
внутри многобайтовой последовательности. И isdigit
работает (хотя и не арабские и другие цифры).
это надмножество ASCII и может содержать все символы Юникода, поэтому определенно использовать с char и string.
Проверьте заголовки HTTP (без учета регистра); они находятся в ISO-8859-1 и предшествуют пустой строке, а затем HTML содержание.
Content-Type: text/html; charset=UTF-8
если нет, там также может быть
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="UTF-8"> <!-- HTML5 -->
ISO-8859-1-это латинский 1, и вам лучше конвертировать из Windows - 1252, расширение Windows Latin-1 с использованием 0x80-0xBF для некоторых специальных символов, таких как кавычки запятой и т. д. Даже браузеры на MacOS поймут это, хотя был указан ISO-8859-1.
библиотеки преобразования: alread упоминается @syam.
преобразование
давайте не будем рассматривать UTF-16. Можно прочитать заголовки и начать до мета-оператора для кодировки как однобайтовые символы.
преобразование из однобайтовой кодировки в UTF-8 может происходить через таблицу. Например, сгенерированный с Java: a const char* table[]
индексируется символом.
table[157] = "\xEF\xBF\xBD";
public static void main(String[] args) {
final String SOURCE_ENCODING = "windows-1252";
byte[] sourceBytes = new byte[1];
System.out.println(" const char* table[] = {");
for (int c = 0; c < 256; ++c) {
String comment = "";
System.out.printf(" /* %3d */ \"", c);
if (32 <= c && c < 127) {
// Pure ASCII
if (c == '\"' || c == '\')
System.out.print("\");
System.out.print((char)c);
} else {
if (c == 0) {
comment = " // Unusable";
}
sourceBytes[0] = (byte)c;
try {
byte[] targetBytes = new String(sourceBytes, SOURCE_ENCODING).getBytes("UTF-8");
for (int j = 0; j < targetBytes.length; ++j) {
int b = targetBytes[j] & 0xFF;
System.out.printf("\x%02X", b);
}
} catch (UnsupportedEncodingException ex) {
comment = " // " + ex.getMessage().replaceAll("\s+", " "); // No newlines.
}
}
System.out.print("\"");
if (c < 255) {
System.out.print(",");
}
System.out.println();
}
System.out.println(" };");
}