Форум программистов, компьютерный форум CyberForum.ru

Преобразовние Utf-16 <=> Utf-8 - C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.80
hard-t
2 / 2 / 0
Регистрация: 21.11.2009
Сообщений: 26
26.08.2011, 13:33     Преобразовние Utf-16 <=> Utf-8 #1
Вопрос казалось бы простой, но нормально ответа на него я пока не нашел. Нужно вывести строчку юникода(UTF-16) в файл с изменением кодировки. Знаю что можно при при wofstream::imbue задать вывод в win-1251 и cp-866. Но как сделть преобразование из utf-16 в utf-8 я найти не могу. Поэтому прошу вашей помощи. Желательно что нибудь кроссплатформенное, поэтому MultiByteToWideChar() не предлагать. Если можно то неотвечайте в стиле: "гугли .." и "смотри ..", а дайте конкретный пример.Благодарю за внимание.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.08.2011, 13:33     Преобразовние Utf-16 <=> Utf-8
Посмотрите здесь:

C++ From UTF-8 to UNICODE
C и UTF-8 C++
Конвертация из ASCII в UTF-32 или UTF-8 в UTF-32 C++
C++ Кириллица в UTF-8
из UTF-8 в Windows-1251 C++
C++ C++, UTF-8 и совместимость
C++, UTF-8, char C++
Считать utf-8 из файла C++
Utf-8. И снова кодировки C++
Libiconv конвертирование в UTF-8? C++
C++ Парсер, utf-8
Кириллицу в UTF-8 C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт С++
 Аватар для ForEveR
7955 / 4717 / 318
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
26.08.2011, 13:39     Преобразовние Utf-16 <=> Utf-8 #2
arabica
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  struct Tab
  {
    unsigned char char_mask;
    unsigned char char_value;
    int shift;
    unsigned long wide_mask;
  };
 
  static const Tab tab[] =
  {
    { char(0x80),  char(0x00),   0*6,    0x7F,   },   // 1 byte sequence
    { char(0xE0),  char(0xC0),   1*6,    0x7FF,  },   // 2 byte sequence
    { char(0xF0),  char(0xE0),   2*6,    0xFFFF, },   // 3 byte sequence
    { 0,           0,            0,      0,      }    // end of table
  };
 
std::codecvt_base::result Arabica::convert::impl::utf8_2_ucs2(
                       const char* from, const char* from_end, const char*& from_next,
                       wchar_t* to, wchar_t* to_limit, wchar_t*& to_next)
{
  from_next = from;
  to_next = to;
 
    while((from_next < from_end) && (to_next < to_limit))
    {
    unsigned char start = static_cast<unsigned char>(*from_next);
 
    const Tab *t = tab;
    for(; t->char_mask; ++t)
    {
      if((start & t->char_mask) == t->char_value)
        break;
    }
 
    if((from_next + (t - tab)) >= from_end)
      break;
 
    unsigned long wide_mask = t->wide_mask;
 
    *to_next = start;
    for(; t != tab; --t)
    {
      from_next++;
      *to_next = (*to_next << 6) | ((*from_next ^ 0x80) & 0xff);
    }
    *to_next &= wide_mask;
 
    ++from_next;
    ++to_next;
  } // while
 
  return (from_next == from_end) ? std::codecvt_base::ok : std::codecvt_base::partial;
} // utf8_2_ucs2


Если подходит То тебе сюда.

Хотя я в свое время предпочел делать примерно так.
iconv

C++
1
2
3
4
5
6
7
8
9
10
11
    std::codecvt_base::result utf16_2_utf8(const char* from, const char* from_end, const char*& from_next,
            char* to, char* to_end, char*& to_next, bool utf16_be)
    {
        from_next = from;
        to_next = to;
        size_t from_size = (from_end - from);
        Impl::iconv_result state = convert(from_next, from_size, to_next, (to_end - to), 
                    (utf16_be ? "UTF-16BE" : "UTF-16LE"), "UTF-8");
        return state == Impl::iconv_ok ? std::codecvt_base::ok : 
          state == Impl::iconv_partial ? std::codecvt_base::partial : std::codecvt_base::error;
    }
или так если UCS2 в UTF8.

C++
1
2
3
4
5
6
7
8
9
10
11
12
template<class CharT>
std::codecvt_base::result ucs2_2_utf8(const CharT* from, const CharT* from_end, const CharT*& from_next,
                                      char* to, char* to_end, char*& to_next, bool ucs2_be)
{
    from_next = from;
    to_next = to;
    size_t from_size = (from_end - from) * sizeof(CharT);
    Impl::iconv_result state = Locale::Convert::convert(from_next, from_size, to_next, (to_end - to), 
            (ucs2_be ? "UCS-2BE" : "UCS-2LE"), "UTF-8");
    return state == Impl::iconv_ok ? std::codecvt_base::ok : 
      state == Impl::iconv_partial ? std::codecvt_base::partial : std::codecvt_base::error;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
namespace Locale
{
namespace Convert
{
namespace Impl
{
    class IconvError:public std::logic_error
    {
    public:
        IconvError(const std::string& string):
            std::logic_error(string)
        {
        }
    };
    
    std::string errno_open();
    std::string errno_convert();
    
    //iconv representation of std::codecvt_base::result.
    enum iconv_result
    {
        iconv_error = std::codecvt_base::error,
        iconv_partial = std::codecvt_base::partial,
        iconv_ok = std::codecvt_base::ok
    };
}//namespace Impl
 
    /*
     * Convert from from_code encoding to to_code encoding using libiconv.
     *
     * @types@
     *    CharT - internal char representation
     *    ExternCharT - external char representation
     * @types@
     *
     * @params@
     *    in_pointer - reference to internal char pointer
     *    in_size - size of internal char buffer
     *    out_pointer - reference to external char pointer
     *    out_size - size of external char buffer
     *    from_code - title of the internal encoding
     *    to_code - title of the external encoding
     * @params@
     *
     * @return@
     *    return iconv_error if iconv can`t convert
     *    return iconv_partial if partial conversion was happened
     *    return iconv_ok if encoding is succesfull
     *    throw exception if iconv handler can`t be created
     * @return
    */ 
 
    template<class CharT, class ExternCharT>
    Impl::iconv_result convert(CharT*& in_pointer, size_t in_size, ExternCharT*& out_pointer, size_t out_size,
            const std::string& from_code, const std::string& to_code)
    {
        iconv_t converter = iconv_open(to_code.c_str(), from_code.c_str());
        if (converter == iconv_t(-1))
        {
            throw Impl::IconvError("Converter opening error: " + Impl::errno_open());
        }
        char* in_pointer_for_conv = (char*)in_pointer;
        char* out_pointer_for_conv = (char*)out_pointer;
        size_t result = iconv(converter, &in_pointer_for_conv, &in_size, &out_pointer_for_conv, &out_size);
        in_pointer = (CharT*)in_pointer_for_conv;
        out_pointer = (ExternCharT*)out_pointer_for_conv;
        if (result == size_t(-1))
        {
            iconv_close(converter);
            if(errno == E2BIG || errno == EINVAL)
                return Impl::iconv_partial;
            return Impl::iconv_error;
        }
        iconv_close(converter);
        return Impl::iconv_ok;
    }
}//namespace Convert
}//namespace Locale
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
26.08.2011, 13:45     Преобразовние Utf-16 <=> Utf-8 #3
http://www.boost.org/doc/libs/1_46_1...c/codecvt.html
Yandex
Объявления
26.08.2011, 13:45     Преобразовние Utf-16 <=> Utf-8
Ответ Создать тему
Опции темы

Текущее время: 20:01. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru