2010-02-17 2 views
2

Я знаком с преобразованиями WideCharToMultiByte и MultiByteToWideChar и может использовать их, чтобы сделать что-то вроде:Windows, C API для UTF8 1252

UTF8 -> UTF16 -> 1252

Я знаю, что Iconv будет делать то, что Мне нужно, но кто-нибудь знает какие-либо MS-библиотеки, которые позволят это в один звонок?

Должно быть, я просто должен забрать библиотеку iconv, но чувствую себя ленивым.

Благодаря

ответ

0

для Windows 1252 в основном эквивалентна латино-1, также известный как ISO-8859-1: Windows-1252 только имеет некоторые дополнительные символы, выделенные в латино-1 зарезервирован диапазон 128-159. Если вы готовы игнорировать эти дополнительные символы и придерживаться латинского-1, то преобразование довольно просто. Попробуйте это:

#include <stddef.h> 

/* 
* Convert from UTF-8 to latin-1. Invalid encodings, and encodings of 
* code points beyond 255, are replaced by question marks. No more than 
* dst_max_len bytes are stored in the destination array. Returned value 
* is the length that the latin-1 string would have had, assuming a big 
* enough destination buffer. 
*/ 
size_t 
utf8_to_latin1(char *src, size_t src_len, 
    char *dst, size_t dst_max_len) 
{ 
    unsigned char *sb; 
    size_t u, v; 

    u = v = 0; 
    sb = (unsigned char *)src; 
    while (u < src_len) { 
     int c = sb[u ++]; 
     if (c >= 0x80) { 
      if (c >= 0xC0 && c < 0xE0) { 
       if (u == src_len) { 
        c = '?'; 
       } else { 
        int w = sb[u]; 
        if (w >= 0x80 && w < 0xC0) { 
         u ++; 
         c = ((c & 0x1F) << 6) 
          + (w & 0x3F); 
        } else { 
         c = '?'; 
        } 
       } 
      } else { 
       int i; 

       for (i = 6; i >= 0; i --) 
        if (!(c & (1 << i))) 
         break; 
       c = '?'; 
       u += i; 
      } 
     } 
     if (v < dst_max_len) 
      dst[v] = (char)c; 
     v ++; 
    } 
    return v; 
} 

/* 
* Convert from latin-1 to UTF-8. No more than dst_max_len bytes are 
* stored in the destination array. Returned value is the length that 
* the UTF-8 string would have had, assuming a big enough destination 
* buffer. 
*/ 
size_t 
latin1_to_utf8(char *src, size_t src_len, 
    char *dst, size_t dst_max_len) 
{ 
    unsigned char *sb; 
    size_t u, v; 

    u = v = 0; 
    sb = (unsigned char *)src; 
    while (u < src_len) { 
     int c = sb[u ++]; 
     if (c < 0x80) { 
      if (v < dst_max_len) 
       dst[v] = (char)c; 
      v ++; 
     } else { 
      int h = 0xC0 + (c >> 6); 
      int l = 0x80 + (c & 0x3F); 
      if (v < dst_max_len) { 
       dst[v] = (char)h; 
       if ((v + 1) < dst_max_len) 
        dst[v + 1] = (char)l; 
      } 
      v += 2; 
     } 
    } 
    return v; 
} 

Обратите внимание, что я делаю нет гарантии об этом коде. Это полностью непроверено.

+1

И как это лучше, чем просто использовать проверенный API, вызывая MultiByteToWideChar, за которым следует WideCharToMultiByte? – Sofahamster

+1

«Лучше»? Что спорное понятие. Вопрос состоял в том, чтобы сделать это в одном вызове функции вместо двух, особенно если эти два являются «MultiByteToWideChar()» и «WideCharToMultiByte()». Мой код делает это. Я не утверждаю, что _wise_ следует избегать 'MultiByteToWideChar()'. Ничтожество, можно указать, что мои функции не позволяют распределить временный буфер. –