如何使用C API将ICU4C UChar *转换为char *(以打印Unicode字符串)?

时间:2013-12-24 10:37:58

标签: c string unicode utf-8 icu

我有一个Unicode UChar *字符串,我需要将它打印到控制台。我用过这个方法

char* UChar_print(const UChar *s, UErrorCode *status, int32_t resultlength)
{

 UConverter *conv;
    char *target=NULL;
    target= malloc(sizeof(UChar) *resultlength );
    int32_t len;
    UErrorCode errorCode;

    errorCode=U_ZERO_ERROR;
    conv = ucnv_open("conv", &errorCode);

    len = ucnv_fromUChars(conv, target, 30000, s, resultlength, &errorCode);
    printf("res %s", target);

    ucnv_close(conv);
    return target;
}

我没有得到正确的输出。 有没有人以前尝试过ucnv_fromUChars?或者知道如何打印UTF-8 UChar字符串?

2 个答案:

答案 0 :(得分:2)

您的代码的主要问题是您使用"conv"作为转换器名称。您应该使用有效的名称。请参阅ICU converter explorer。如果您的终端不支持Unicode,则应使用ucnv_setFromUCallBack设置错误回调来处理转换错误。

然后计算目标缓冲区大小是错误的。

尝试类似的东西(未经测试):

UErrorCode UChar_print(const UChar *s, int32_t resultlength)
{
    UErrorCode errorCode = U_ZERO_ERROR;

    // Converting to ASCII, or whatever your terminal supports.
    UConverter *conv = ucnv_open("ASCII", &errorCode);
    // You forgot to check whether uconv_open succeeded.
    if (conv == NULL) return errorCode;

    // Compute target capacity as recommended in the ICU reference.
    // Alternatively, you could pre-flight the conversion to get the
    // actual buffer size needed.
    int32_t targetCap = UCNV_GET_MAX_BYTES_FOR_STRING(resultlength,
                                                      ucnv_getMaxCharSize(conv));
    char *target = malloc(targetCap);
    // Here you should check whether the allocation failed.

    // Pass the actual target buffer size, not some arbitrary number. 
    ucnv_fromUChars(conv, target, targetCap, s, resultlength, &errorCode);

    if (errorCode == U_ZERO_ERROR) {
        printf("res %s", target);
    }

    // Don't forget to free the result.
    free(target);

    ucnv_close(conv);

    return errorCode;
}

答案 1 :(得分:0)

以下是我使用的一些辅助功能,利用了ICU的转换功能。希望它们可能会有用。

const char* icustring2char(icu::UnicodeString convertme) {
    std::string result;
    convertme.toUTF8String(result);
    return result.c_str();
}

const char* icuchar2char(UChar convertme) {
    icu::UnicodeString temp(convertme);
    return icustring2char(temp);
}