问题描述
我熟悉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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!