ICU4C函数ucnv_convert

本文介绍如何使用ICU4C库进行字符编码转换,包括下载安装、使用ucnv_convert函数实现不同编码间的转换,并详细解释了参数设置及错误处理。

ICU4C 的获得:
从网址: http://site.icu-project.org/download
可以下载 windows 所需的库和头文件,当然还有 DLL 文件 :)
本文测试用的 4.2 版来源于: http://icu-project.org/download/4.2.html

ucnv_convert 函数:
头文件: unicode\ucnv.h
库文件: lib\icuuc.lib

函数声明:

[cpp]  view plain copy
  1. U_STABLE int32_t U_EXPORT2  
  2. ucnv_convert(const char *toConverterName,  
  3.              const char *fromConverterName,  
  4.              char *target,  
  5.              int32_t targetCapacity,  
  6.              const char *source,  
  7.              int32_t sourceLength,  
  8.              UErrorCode *pErrorCode);  
  9.   
  10. // 下面是 ICU4C 4.2 的测试代码  
  11.  const char *toConverterName= "utf8" 
  12.  const char *fromConverterName "gb2312" 
  13.  char target [100];  
  14.  int32_t targetCapacity 100;  
  15.  const char *source="呵呵" 
  16.  int32_t sourceLength -1;  
  17.  UErrorCode ErrorCode U_ZERO_ERROR; // 文档中说该值必须初始化为U_ZERO_ERROR,其实如果不初始化该值而且转换中没有出错时该值是不会被填写的,即未初始化前的值  
  18.  int ret ucnv_convert(toConverterName, // utf8 或 utf-8 效果是一样的  
  19.   fromConverterName, // gbk 与 gb2312 好像区别不大,用 gbk 可能会好些  
  20.   target,     
  21.   targetCapacity, // 详见下面  
  22.   source,  
  23.   sourceLength, // 长度为 -1 表明 NULL 终止的字符串  
  24.   &ErrorCode);  // 该值不能为空,否则函数返回值为 并不做任何转换  
  25.     // 返回值 ret 为整个源字符串 source 转换后的长度(即使 targetCapacity 空间不足也是如此)  


 

// targetCapacity 与 转换所需空间的关系:
如果targetCapacity小于转换所需空间:
1. ret 的值为整个源串 source 转换后的字节数,该值不含 0 结尾的长度
2. target 中会填充 targetCapacity 所指定的转换的字节数,并且不会有 0 填充 target 的结尾
3. ErrorCode 会被置为 U_BUFFER_OVERFLOW_ERROR

如果targetCapacity等于转换所需空间:
1. ret 的值为整个源串 source 转换后的字节数,该值不含 0 结尾的长度
2. target 中会填充 targetCapacity 所指定的转换的字节数,并且不会有 0 填充 target 的结尾
3. ErrorCode 会被置为 U_STRING_NOT_TERMINATED_WARNING

如果targetCapacity大于转换所需空间:
1. ret 的值为整个源串 source 转换后的字节数,该值不含 0 结尾的长度
2. target 中会填充 ret 的字节数, target[ret] 处被填为 0 表示 target 字符串结束
3. ErrorCode 会被置为 U_ZERO_ERROR

其他:
 target 可被置为 NULL (当然此时 targetCapacity 应该为 0),
 此时:
 1. ret 返回转换所需空间(该值不含 0 结尾的长度)
 2. ErrorCode 会被置为 U_BUFFER_OVERFLOW_ERROR
 可以使用这种方法来计算转换所需空间,但感觉不是太值 

<think> 我们正在讨论ICU(International Components for Unicode)库中的函数UCNV_FROM_U_CALLBACK_SUBSTITUTE()是一个回调函数,用于处理在将Unicode字符串转换为目标字符集时遇到无法映射的字符的情况。 根据ICU文档,当转换器遇到一个无法映射到目标字符集的Unicode字符时,它会调用一个回调函数UCNV_FROM_U_CALLBACK_SUBSTITUTE()是ICU提供的一个标准回调函数,它的功能是用一个替换字符(通常是问号?或指定的替换字符串)来替换无法映射的字符。 使用方法: 在设置转换器时,可以使用ucnv_setFromUCallBack()函数来设置这个回调函数。具体步骤如下: 1. 创建一个转换器(使用ucnv_open()等函数)。 2. 使用ucnv_setFromUCallBack()将回调函数设置为UCNV_FROM_U_CALLBACK_SUBSTITUTE。 3. 在进行转换时,如果遇到无法映射的字符,就会调用这个回调函数,用替换字符替代。 注意:UCNV_FROM_U_CALLBACK_SUBSTITUTE是ICU内置的一个回调函数,因此可以直接使用,而不需要自己实现。 函数原型(在C中): U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_SUBSTITUTE ( const void *context, UConverterFromUnicodeArgs *fromUArgs, const UChar* codeUnits, int32_t length, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode *err ); 参数说明: - context: 用户提供的上下文,通常为NULL,因为UCNV_FROM_U_CALLBACK_SUBSTITUTE是预定义的,不需要额外上下文。 - fromUArgs: 提供转换状态和输出缓冲区等信息。 - codeUnits: 指向无法转换的Unicode代码单元的指针。 - length: 代码单元的数量(1或2,因为UChar是16位,而补充平面字符由两个代码单元组成)。 - codePoint: 无法转换的Unicode代码点(如果可用,否则为U+FFFF)。 - reason: 回调的原因(例如,无法映射的字符,非法序列等)。 - err: 错误码,可以设置错误信息。 该回调函数的行为是:当遇到无法映射的字符时,它会将替换字符(由转换器指定,通常是U+FFFD替换字符,但实际输出取决于转换器的配置)输出到目标缓冲区。 在ICU中,还可以通过ucnv_setSubstChars()来设置替换字符串(例如,用"?"或"�"替换)。 示例代码片段(C语言): ```c #include <unicode/ucnv.h> #include <unicode/uchar.h> #include <unicode/ustring.h> UErrorCode status = U_ZERO_ERROR; UConverter *converter = ucnv_open("ISO-8859-1", &status); // 打开一个转换器 if (U_SUCCESS(status)) { // 设置替换字符串,例如一个问号 char substitute[] = "?"; ucnv_setSubstChars(converter, substitute, 1, &status); // 设置回调函数为SUBSTITUTE ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_SUBSTITUTE, NULL, NULL, NULL, &status); // 然后使用转换器进行转换... // ... ucnv_close(converter); } ``` 注意:UCNV_FROM_U_CALLBACK_SUBSTITUTE处理的是从Unicode到目标字符集的转换(即“from Unicode”)。对于相反方向的转换,有类似的回调函数UCNV_TO_U_CALLBACK_SUBSTITUTE。 功能总结: 该回调函数用于在转换过程中遇到无法映射的字符时,用替换字符(串)代替,从而避免转换失败。这是处理转换错误的常用方法。 引用: ICU官方文档中关于转换回调的部分[^1]。 §§相关问题§§ 1. ICU库中还有哪些预定义的回调函数用于处理转换错误? 2. 如何自定义一个转换回调函数? 3. 在字符转换过程中,除了替换,还有哪些处理错误的方式? </think> ### UCNV_FROM_U_CALLBACK_SUBSTITUTE() 函数详解 #### 功能说明 `UCNV_FROM_U_CALLBACK_SUBSTITUTE()` 是 ICU(International Components for Unicode)库中的预定义回调函数,主要用于处理 **Unicode 到目标字符集转换过程中的不可映射字符**。当转换器遇到无法在目标字符集中表示的 Unicode 字符时,该函数会自动用预定义的替换字符(通常是 `U+FFFD` 或自定义字符)进行替换。 #### 核心特性 1. **错误处理机制** 替代无效字符而非抛出错误,确保转换过程不会因个别字符失败。 2. **标准化替换** 默认使用 Unicode 替换字符 `�` (U+FFFD),但可通过 `ucnv_setSubstChars()` 自定义替换字符串。 3. **预定义实现** 作为 ICU 内置回调,无需用户额外实现处理逻辑。 #### 使用方法 1. **设置转换器回调** ```c #include <unicode/ucnv.h> UErrorCode status = U_ZERO_ERROR; UConverter* converter = ucnv_open("ISO-8859-1", &status); // 打开目标字符集转换器 // 设置替换回调函数 ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_SUBSTITUTE, NULL, NULL, NULL, &status); ``` 2. **自定义替换字符**(可选) ```c const char* subChars = "?"; // 自定义替换字符 ucnv_setSubstChars(converter, subChars, 1, &status); // 长度为1 ``` 3. **执行转换** 使用 `ucnv_fromUChars()` 等函数转换时,不可映射字符将被自动替换。 #### 典型应用场景 - 将 UTF-16 文本转换为遗留字符集(如 ISO-8859-1) - 处理包含表情符号或特殊符号的文本转换 - 需要容错处理的国际化文本处理系统 #### 注意事项 1. 仅作用于 **from Unicode** 的转换方向(目标字符集为非 Unicode)。 2. 替换可能导致信息丢失,需评估业务场景的容忍度。 3. 可通过 `UCNV_FROM_U_CALLBACK_STOP` 等回调实现不同错误处理策略[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值