适用于UTF8的Windows C API至1252 [英] Windows C API for UTF8 to 1252

查看:99
本文介绍了适用于UTF8的Windows C API至1252的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我熟悉WideCharToMultiByte和MultiByteToWideChar转换,可以使用它们来做类似的事情:

I'm familiar with WideCharToMultiByte and MultiByteToWideChar conversions and could use these to do something like:

UTF8-> UTF16-> 1252

UTF8 -> UTF16 -> 1252

我知道iconv可以满足我的需要,但是有人知道任何允许在一次调用中实现此功能的MS库吗?

I know that iconv will do what I need, but does anybody know of any MS libs that will allow this in a single call?

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

I should probably just pull in the iconv library, but am feeling lazy.

谢谢

推荐答案

Windows 1252主要等同于latin-1,又名ISO-8859-1:Windows-1252只是在latin-1保留范围内分配了一些其他字符128-159.如果您准备忽略那些多余的字符,并坚持使用latin-1,那么转换就很容易了.试试这个:

Windows 1252 is mostly equivalent to latin-1, aka ISO-8859-1: Windows-1252 just has some additional characters allocated in the latin-1 reserved range 128-159. If you are ready to ignore those extra characters, and stick to latin-1, then conversion is rather easy. Try this:

#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;
}   

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

Note that I make no guarantee about this code. This is completely untested.

这篇关于适用于UTF8的Windows C API至1252的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆