我的软件在UTF8中得到的字符串比我转换为ISO 8859 1所需的字符串多。我知道UTF8域比iso
8859大。但是UTF8中的数据先前已从ISO上转换,所以我不应该错过任何内容。
我想知道是否存在从UTF8转换为iso-8859-1的简单/直接方法。
谢谢
这是您可能会发现有用的功能: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+006E U+0303
变成U+00F1
。我不麻烦重组,因为iconv也没有。
该函数对于字符串访问非常小心。它永远不会扫描超出缓冲区。输出缓冲区必须比长度长一个字节,因为它总是附加字符串末尾的NUL字节。该函数返回输出中的字符数(字节),不包括字符串末尾的NUL字节。
/* UTF-8 to ISO-8859-1/ISO-8859-15 mapper.
* Return 0..255 for valid ISO-8859-15 code points, 256 otherwise.
*/
static inline unsigned int to_latin9(const unsigned int code)
{
/* Code points 0 to U+00FF are the same in both. */
if (code < 256U)
return code;
switch (code) {
case 0x0152U: return 188U; /* U+0152 = 0xBC: OE ligature */
case 0x0153U: return 189U; /* U+0153 = 0xBD: oe ligature */
case 0x0160U: return 166U; /* U+0160 = 0xA6: S with caron */
case 0x0161U: return 168U; /* U+0161 = 0xA8: s with caron */
case 0x0178U: return 190U; /* U+0178 = 0xBE: Y with diaresis */
case 0x017DU: return 180U; /* U+017D = 0xB4: Z with caron */
case 0x017EU: return 184U; /* U+017E = 0xB8: z with caron */
case 0x20ACU: return 164U; /* U+20AC = 0xA4: Euro */
default: return 256U;
}
}
/* Convert an UTF-8 string to ISO-8859-15.
* All invalid sequences are ignored.
* Note: output == input is allowed,
* but input < output < input + length
* is not.
* Output has to have room for (length+1) chars, including the trailing NUL byte.
*/
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++); /* Valid codepoint */
else
if (*in < 192)
in++; /* 10000000 .. 10111111 are invalid */
else
if (*in < 224) { /* 110xxxxx 10xxxxxx */
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) { /* 1110xxxx 10xxxxxx 10xxxxxx */
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) { /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
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) { /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
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) { /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
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++; /* 11111110 and 11111111 are invalid */
/* Terminate the output string. */
*out = '\0';
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)。主要区别在于这些函数返回动态分配的副本,并保持原始字符串不变。
问题内容: 我正在阅读XML文档(UTF-8),并最终使用ISO-8859-1在网页上显示内容。正如预期的那样,有几个字符显示不正确,比如,和(他们显示为?)。 是否可以将这些字符从UTF-8转换为ISO-8859-1? 这是我编写的尝试此功能的代码段: 我不太确定发生了什么问题,但是我认为是readLine()引起了麻烦(因为字符串将是Java / UTF-16编码的?)。我尝试的另一种变化
我想知道如何将此Twilio CURL代码转换为RestClient我被困在请求中。我不知道如何格式化它的顺序传递Twilio SID,令牌,从,到和正文短信。 为此: 这是我的代码,现在编译100%,在我运行代码后,我得到一个响应“完成”没有错误消息,也没有在twilio仪表板上的条目,它不会发送短信,任何想法您的帮助将不胜感激。
我目前正在将我的“旧”基于Python的聊天机器人改写成golang。我遇到的一个问题是我不能将PDF转换成jpeg。我想这样做,这样我就可以轻松地将它发送到聊天室。 已经用bimg(根本不起作用)和imagemagick(gopkg.in/gographics/imagick.v3/imagick)尝试过这一点,正如在对另一个线程的回答中提供的那样:https://stackoverflow.c
问题内容: 因此,我有一个方法,其中包含3种不同类型的参数: ,和。因此,想法是使用泛型来最小化接口 但是我已经意识到,是在运行时,and 参数实际上会使那失败。这是有道理的,这只是我的一厢情愿。 但是,如果我尝试将a强制转换为双精度,编译器将吠叫: 无法使用参数’(T)’调用类型’Double’的初始化程序 我认为这也是有道理的,因为没有Double的初始化程序需要Generic。 因此,看起来
问题内容: 我的某些脚本使用了不同的编码,当我尝试将它们组合时,这已成为一个问题。 但是我无法更改它们使用的编码,而是要更改脚本A的结果编码,并将其用作脚本B中的参数。 所以:有什么简单的方法可以在PHP中将字符串从UTF-8更改为ISO-88591?我看过utf_encode和_decode,但是他们没有做我想要的。为什么不存在任何“ utf2iso()”功能或类似功能? 我认为我的字符无法以I
我正在尝试创建一个神经网络来下棋,但首先,我需要将棋盘转换为整数列表。我正在使用国际象棋棋盘和游戏的python国际象棋模块。我目前有一个国际象棋棋盘类,但找不到将其转换为列表的方法。 我试过使用方法,但它返回的格式方案很难转换。 下面是我需要的代码: 现在,使用我得到的方法 如您所见,解析并转换为整数列表非常困难,因为有和。 预期的输出是这样的(逐行): 例如,这些可以是映射到PEICE的整数: