2015-07-08 5 views
2

Мне нужно преобразовать между UTF-8, UTF-16 и UTF-32 для разных API/модулей, и, поскольку я знаю, есть возможность использовать C++ 11 am, глядя на новые типы строк.std :: преобразование u32string в/из std :: string и std :: u16string

Похоже, что я могу использовать string, u16string и u32string для UTF-8, UTF-16 и UTF-32. Я также нашел codecvt_utf8 и codecvt_utf16, которые выглядят, чтобы быть в состоянии выполнить преобразование между char или char16_t и char32_t и то, что выглядит как более высокий уровень wstring_convert но только, кажется, работает с байтами/std::string и не очень много документации.

Я хотел бы использовать wstring_convert как-то для UTF-16 ↔ UTF-32 и UTF-8 ↔ UTF-32? Я действительно нашел примеры для UTF-8 для UTF-16, что я даже не уверен, что будет правильно в Linux, где wchar_t обычно считается UTF-32 ... Или сделать что-то более сложное с этими вещами codecvt напрямую?

Или это просто все еще не в состоянии использования, и я должен придерживаться своих существующих небольших подпрограмм с использованием 8, 16 и 32-битных целых чисел без знака?

+0

'wchar_t' не "рассматривается для UTF-32". 'wchar_t' используется для широких символов. Вы можете конвертировать широкие символы в UTF-foo, если хотите. –

+0

Я бы не стал делать ставку на любую функцию unicode на C++ - вы можете попробовать что-то вроде uconv: https://en.wikipedia.org/wiki/Uconv –

+0

, поэтому вы хотите использовать типы u16 * u32 *, я упомянул только wchar_t, потому что примеры google выглядят использовать его, и потому что wstring_convert является стандартным, но u16string_convert, u32string_convert и т. д., похоже, не существует, значит, это означает, что я пропустил что-то о wstring_convert? –

ответ

14

Если вы читаете документацию на CppReference.com для wstring_convert, codecvt_utf8, codecvt_utf16 и codecvt_utf8_utf16, страницы включают в себя таблицу, которая говорит вам именно то, что вы можете использовать для различных преобразований UTF.

table

И да, вы будете использовать std::wstring_convert для облегчения перехода между различными UTFs. Несмотря на свое название, он не ограничивается только std::wstring, он фактически работает с любым типом std::basic_string (которые основаны на std::string, std::wstring и std::uXXstring).

шаблон класса станд :: wstring_convert выполняет преобразование между байтами строкой std::string и строками широких std::basic_string<Elem>, с использованием индивидуального преобразования кода фасета Codecvt. std :: wstring_convert предполагает право собственности на фазу преобразования и не может использовать фасет, управляемый языковой версией. Стандартные грани, подходящие для использования с std :: wstring_convert, - это std :: codecvt_utf8 для конверсий UTF-8/UCS2 и UTF-8/UCS4 и std :: codecvt_utf8_utf16 для конверсий UTF-8/UTF-16.

Например:

typedef std::string u8string; 

u8string To_UTF8(const std::u16string &s) 
{ 
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> conv; 
    return conv.to_bytes(s); 
} 

u8string To_UTF8(const std::u32string &s) 
{ 
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv; 
    return conv.to_bytes(s); 
} 

std::u16string To_UTF16(const u8string &s) 
{ 
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> conv; 
    return conv.from_bytes(s); 
} 

std::u16string To_UTF16(const std::u32string &s) 
{ 
    std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t> conv; 
    std::string bytes = conv.to_bytes(s); 
    return std::u16string(reinterpret_cast<const char16_t*>(bytes.c_str()), bytes.length()/sizeof(char16_t)); 
} 

std::u32string To_UTF32(const u8string &s) 
{ 
    std::wstring_convert<codecvt_utf8<char32_t>, char32_t> conv; 
    return conv.from_bytes(s); 
} 

std::u32string To_UTF32(const std::u16string &s) 
{ 
    const char16_t *pData = s.c_str(); 
    std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t> conv; 
    return conv.from_bytes(reinterpret_cast<const char*>(pData), reinterpret_cast<const char*>(pData+s.length())); 
} 
+0

Да, я видел и упоминал эти типы. Но я хотел бы обернуть их для типов std :: basic_string с ошибкой и обработкой буфера (что, по-видимому, мало влияет на простую функцию кодирования/декодирования utf-8 и utf-16?Как я уже сказал, wstring_convert казался «более высоким уровнем», но не видел, как его шаблонировать для всех применимых случаев. –

+0

Итак, я посмотрел на него еще, я все еще не вижу, как будет работать преобразование u16string/UTF-16 и u32string/UTF-32? Ни один из экземпляров шаблона для wstring_convert или codecvt_utf16, по-видимому, не принимает оба значения, а скорее хочет std :: string? –

+0

Я добавил примеры к моему ответу. –

Смежные вопросы