2

我熟悉 WideCharToMultiByte 和 MultiByteToWideChar 转换,可以使用它们来执行以下操作:

UTF8 -> UTF16 -> 1252

我知道 iconv 会做我需要的,但是有人知道任何 MS 库可以在一次调用中允许这样做吗?

我可能应该只是拉入 iconv 库,但我感觉很懒。

谢谢

4

1 回答 1

0

Windows 1252 基本上等同于 latin-1,即 ISO-8859-1:Windows-1252 只是在 latin-1 保留范围 128-159 中分配了一些额外的字符。如果您准备好忽略那些多余的字符,并坚持使用 latin-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;
}   

请注意,我不保证此代码。这是完全未经测试的。

于 2010-02-17T19:14:50.643 回答