有没有办法将UTF8转换为iso

有没有办法将UTF8转换为iso,第1张

有没有办法将UTF8转换为iso

这是您可能会发现有用的功能:

utf8_to_latin9()
。它可以转换为
ISO-8859-15
(包括欧元,
ISO-8859-1
但没有),但是对于->
-> 往返的
UTF-8
->
ISO-8859-1
转换部分,它也可以正常工作。
ISO-8859-1``UTF-8``ISO-8859-1

函数将忽略与

//IGNORE
iconv的标志类似的无效代码点,但不会重组分解的UTF-8序列;也就是说,它不会
U+006EU+0303
变成
U+00F1
。我不麻烦重组,因为iconv也没有。

该函数对于字符串访问非常小心。它永远不会扫描超出缓冲区。输出缓冲区必须比长度长一个字节,因为它总是附加字符串末尾的NUL字节。该函数返回输出中的字符数(字节),不包括字符串末尾的NUL字节。

static inline unsigned int to_latin9(const unsigned int pre){        if (pre < 256U)        return pre;    switch (pre) {    case 0x0152U: return 188U;     case 0x0153U: return 189U;     case 0x0160U: return 166U;     case 0x0161U: return 168U;     case 0x0178U: return 190U;     case 0x017DU: return 180U;     case 0x017EU: return 184U;     case 0x20ACU: return 164U;     default:      return 256U;    }}size_t utf8_to_latin9(char *const output, const char *const input, const size_t length){    unsigned char  *out = (unsigned char *)output;    const unsigned char       *in  = (const unsigned char *)input;    const unsigned char *const end = (const unsigned char *)input + length;    unsigned int    c;    while (in < end)        if (*in < 128) *(out++) = *(in++);         else        if (*in < 192) in++;            else        if (*in < 224) {         if (in + 1 >= end)     break; if ((in[1] & 192U) == 128U) {     c = to_latin9( (((unsigned int)(in[0] & 0x1FU)) << 6U)       |  ((unsigned int)(in[1] & 0x3FU)) );     if (c < 256)         *(out++) = c; } in += 2;        } else        if (*in < 240) {         if (in + 2 >= end)     break; if ((in[1] & 192U) == 128U &&     (in[2] & 192U) == 128U) {     c = to_latin9( (((unsigned int)(in[0] & 0x0FU)) << 12U)       | (((unsigned int)(in[1] & 0x3FU)) << 6U)       |  ((unsigned int)(in[2] & 0x3FU)) );     if (c < 256)         *(out++) = c; } in += 3;        } else        if (*in < 248) {         if (in + 3 >= end)     break; if ((in[1] & 192U) == 128U &&     (in[2] & 192U) == 128U &&     (in[3] & 192U) == 128U) {     c = to_latin9( (((unsigned int)(in[0] & 0x07U)) << 18U)       | (((unsigned int)(in[1] & 0x3FU)) << 12U)       | (((unsigned int)(in[2] & 0x3FU)) << 6U)       |  ((unsigned int)(in[3] & 0x3FU)) );     if (c < 256)         *(out++) = c; } in += 4;        } else        if (*in < 252) {         if (in + 4 >= end)     break; if ((in[1] & 192U) == 128U &&     (in[2] & 192U) == 128U &&     (in[3] & 192U) == 128U &&     (in[4] & 192U) == 128U) {     c = to_latin9( (((unsigned int)(in[0] & 0x03U)) << 24U)       | (((unsigned int)(in[1] & 0x3FU)) << 18U)       | (((unsigned int)(in[2] & 0x3FU)) << 12U)       | (((unsigned int)(in[3] & 0x3FU)) << 6U)       |  ((unsigned int)(in[4] & 0x3FU)) );     if (c < 256)         *(out++) = c; } in += 5;        } else        if (*in < 254) {         if (in + 5 >= end)     break; if ((in[1] & 192U) == 128U &&     (in[2] & 192U) == 128U &&     (in[3] & 192U) == 128U &&     (in[4] & 192U) == 128U &&     (in[5] & 192U) == 128U) {     c = to_latin9( (((unsigned int)(in[0] & 0x01U)) << 30U)       | (((unsigned int)(in[1] & 0x3FU)) << 24U)       | (((unsigned int)(in[2] & 0x3FU)) << 18U)       | (((unsigned int)(in[3] & 0x3FU)) << 12U)       | (((unsigned int)(in[4] & 0x3FU)) << 6U)       |  ((unsigned int)(in[5] & 0x3FU)) );     if (c < 256)         *(out++) = c; } in += 6;        } else in++;            *out = '';    return (size_t)(out - (unsigned char *)output);}

请注意,您可以为

to_latin9()
函数中的特定代码点添加自定义音译,但仅限于一个字符的替换。

就目前而言,该函数可以安全地进行就地转换:输入和输出指针可以相同。输出字符串将永远不会长于输入字符串。如果您的输入字符串有多余的空间(例如,它以NUL终止该字符串),则可以安全地使用上述函数将其从UTF-8转换为ISO-8859-1
/ 15。我特意以此方式编写它,因为它可以在嵌入式环境中为您节省一些精力,尽管这种方法的工作量有限。定制和扩展。

编辑:

在此答案的编辑中,我包括了一对转换函数,用于将拉丁1/9转换为UTF-8(或从UTF-8转换为ISO-8859-1或-15转换为UTF-8)。主要区别在于这些函数返回动态分配的副本,并保持原始字符串不变。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4921583.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存