当前位置: 首页 > 知识库问答 >
问题:

使用icu库将UTF-8转换为UCS-2

洪伟彦
2023-03-14

我目前正在工作,并击中一个问题与转换UTF-8字符串到UCS-2字符串与icu库。在图书馆里有几种方法可以做到这一点,但是到目前为止,它们似乎都不起作用,但是考虑到这个图书馆的受欢迎程度,我假设我做错了什么。

首先是通用代码。在所有情况下,我都是在对象上创建和传递字符串,但在它达到转换步骤之前,没有任何操作。

目前使用的utf-8字符串只是“ĩ”。

为了简单起见,我将在这段代码中表示作为uniString使用的字符串

UErrorCode resultCode = U_ZERO_ERROR;

UConverter* m_pConv = ucnv_open("ISO-8859-1", &resultCode);

// Change the callback to error out instead of the default            
const void* oldContext;
UConverterFromUCallback oldFromAction;
UConverterToUCallback oldToAction;
ucnv_setFromUCallBack(m_pConv, UCNV_FROM_U_CALLBACK_STOP, NULL, &oldFromAction, &oldContext, &resultCode);
ucnv_setToUCallBack(m_pConv, UCNV_TO_U_CALLBACK_STOP, NULL, &oldToAction, &oldContext, &resultCode);

int32_t outputLength = 0;
int bodySize = uniString.length();
int targetSize = bodySize * 4;
char* target = new char[targetSize];                       

printf("Body: %s\n", uniString.c_str());
if (U_SUCCESS(resultCode))
{
    // outputLength = ucnv_convert("ISO-8859-1", "UTF-8", target, targetSize, uniString.c_str(), bodySize, &resultCode);
    outputLength = ucnv_fromAlgorithmic(m_pConv, UCNV_UTF8, target, targetSize, uniString.c_str(),
        uniString.length(), &resultCode);
    ucnv_close(m_pConv);
}
printf("ISO-8859-1 DGF just tried to convert '%s' to '%s' with error '%i' and length '%i'", uniString.c_str(), 
    outputLength ? target : "invalid_char", resultCode, outputLength);

if (resultCode == U_INVALID_CHAR_FOUND || resultCode == U_ILLEGAL_CHAR_FOUND || resultCode == U_TRUNCATED_CHAR_FOUND)
{
    if (resultCode == U_INVALID_CHAR_FOUND)
    {
        printf("Unmapped input character, cannot be converted to Latin1");                    

        m_pConv = ucnv_open("UCS-2", &resultCode);
        if (U_SUCCESS(resultCode))
        {
            // outputLength = ucnv_convert("UCS-2", "UTF-8", target, targetSize, uniString.c_str(), bodySize, &resultCode);
            outputLength = ucnv_fromAlgorithmic(m_pConv, UCNV_UTF8, target, targetSize, uniString.c_str(),
                uniString.length(), &resultCode);
            ucnv_close(m_pConv);
        }

        printf("UCS-2 DGF just tried to convert '%s' to '%s' with error '%i' and length '%i'", uniString.c_str(), 
            outputLength ? target : "invalid_char", resultCode, outputLength);

        if (U_SUCCESS(resultCode))
        {
            pdus = SegmentText(target, pText, SEGMENT_SIZE_UNICODE_MAX, true);
        }
    }
    else
    {
        printf("DecodeText(): Text contents does not appear to be valid UTF-8");
    }
}
else
{
    printf("DecodeText(): Text successfully converted to Latin1");
    std::string newBody(target, outputLength);
    pdus = SegmentText(newBody, pPdu, SEGMENT_SIZE_MAX);
}

问题在于ucnv\U from algorithmic函数为ucs-2转换抛出了一个错误U INVALID\U CHAR\U FOUND。这对于ISO-8859-1尝试是有意义的,但对于ucs-2则没有意义。

另一个尝试是使用ucnv_convert,您可以看到它被注释掉了。此函数尝试转换,但在ISO-8859-1尝试中没有失败。

所以问题是,是否有人有过这些函数的经验,并且看到了一些不正确的东西,或者这个角色的转换假设有一些不正确的地方?

共有1个答案

申屠昆
2023-03-14

在调用ucnv\U open之前,您需要将resultCode重置为U\U ZERO\U ERROR。引自手册:

“如果(U_FAILURE(errorCode)){立即返回;},则ICU函数将引用(C)或指针(C)带到URERRORCODE第一次测试”因此,在这类函数链中,设置错误代码的第一个函数会导致以下函数不执行任何操作“

 类似资料:
  • 我的Git存储库中有一个文件有多个提交,它是用Windows使用的16位Unicode(UCS-2)编码的。 正因为如此,Git认为它是一个二进制文件,而不是文本文件,我看不到不同提交所做的更改。 有没有办法将该文件追溯转换为UTF-8,即重建历史记录,就好像该文件一直是UTF-8,而我一直将其提交为UTF-8文件,而不是16位Unicode文件?

  • 问题内容: 我已阅读以下有关通过GoogleDocs将UTF-8编码的(希伯来语)XLS转换为CSV的建议,并且可以正常工作。当我在Sublime2中使用utf8编码打开CSV时,希伯来语正确显示。但是,当我尝试使用SQLyog将数据导入到我的数据库中时,在确保将我的目标表和导入定义都设置为UTF8之后,我变得很乱,例如: ⒚椔 我哪里出问题了? 问题答案: 从excel导出到csv的最佳方法是:

  • 我需要转换UTF-8字符集到Windows 1252使用PHP和我没有太多的运气到目前为止。我的目标是将文本传输到第三方系统,并排除任何不在Windows 1252字符集中的字符。 我尝试了iconv和mb_convert_编码,但都得到了意想不到的结果。 两者的输出均为“K”?本哈文? 我没有料到会有这样的结果?”s,因为这些字符在WINDOWS-1252字符集中。 有人能帮我解释一下吗。

  • 我试图保存一个字符串在希伯来文文件,同时有文件ANSI编码。恐怕所有的尝试都失败了。 PHP文件本身是UTF-8 这是我正在尝试的代码: 由于某种原因,返回false。 另一次尝试是: 这返回一个空字符串。当这不起作用时,将输出字符集更改为Windows-1255的工作。所以函数本身工作,但由于某种原因,它不转换为1252。 我运行这个函数之前和之后的和打印的结果 在图标之前编码是UTF-8,在图

  • 问题内容: 我们有一个数据输入人员,他在Windows上使用UTF-16编码,并且希望拥有utf-8并删除BOM。utf-8转换有效,但BOM仍然存在。我将如何删除?这是我目前拥有的: 如果我使用hexdump -CI,请参阅: 在结果文件中。如何删除物料清单? 谢谢 问题答案: 只需使用和: 将为您摆脱BOM表(并推断出字节序)。

  • 嗨,我在Python中将utf-8 json转换成unicode escape json时遇到了一些问题 我知道如何将utf-8.txt转换为unicodeescape.txt 但是,我在Python中使用json模块时遇到了上面应用的问题,如下所示 它保存得很好,但是,当涉及到json中的双引号(“)时,它会自动添加双反斜杠(\\),因此unicode-esc.json文件在调用python脚本