请帮助我使用ICU将UCS-2字符串转换为UTF-8?
我使用以下代码,但它无法正常工作。
UErrorCode status = U_ZERO_ERROR;
UConverter *conv;
char buf[1000];
int32_t buflen;
conv = ucnv_open("utf-8", &status);
if (U_FAILURE(status))
{
LOG(L_ERROR, "%s: Can not open the ICU converter\n", __FUNCTION__);
}
else
{
buflen = ucnv_fromUChars(conv, buf, sizeof(buf), (UChar*)sms->message.s, sms->message.len, &status);
if (U_FAILURE(status))
{
LOG(L_ERROR, "%s: Error in conversion: %s\n", __FUNCTION__, u_errorName(status));
}
}
LOG(L_DEBUG, "%s: Conversion made ...\n", __FUNCTION__);
hexdump(sms->message.s, sms->message.len);
hexdump(buf, buflen);
sms->消息是一个结构:
typedef struct str
{
char *s;
int len;
} str_t;
hexdump打印以下内容(输入文字:" aaaa"):
[DEBUG] add_recv_sms_to_db: Conversion made ...
000000: 00 61 00 61 00 61 00 61 .a.a.a.a
000000: e6 84 80 e6 84 80 e6 84 80 e6 84 80 00 00 49 00 ..............I.
答案 0 :(得分:0)
e6 84 80
是U+6100的UTF-8,是CJK统一表意文字。看起来sms->message.s
是小端的,而你的系统是用大端解释它(所以0x0061
变成0x6100
)。
您可以使用UCNV_UTF16_LittleEndian
转换器,或者只是在将sms->message.s
传递给ICU之前执行字节交换。
答案 1 :(得分:0)
我不确定它是否与@ecatmur发现的endiannes问题相关联,但您将sms->message.s
char*
投射到Uchar*
查看here:
将UChar定义为UCHAR_TYPE,如果是#defined(例如,定义为char16_t),或者将wchar_t定义为16位宽;总是假设没有签名。
如果两者都不可用,则将UChar定义为uint16_t。
这使得UChar平台依赖的定义允许直接字符串类型与具有16位wchar_t类型的平台兼容。
你确定这个演员是安全的吗?