跨平台Unicode字符编码转换,ICU库简单介绍
一、简介
ICU是一套成熟的、广泛使用的C/C++和java库,提供Unicode和全球化支持、可移值、在所有平台上以及在C/C++和Java软件之间为应用程序提供相同的结果。
ICU提供的服务一些亮点:
- Code Page Conversion: Convert text data to or from Unicode and nearly any other character set or encoding.
- Collation:Compare strings according to the conventions and standards of a particular language,region or country.
- Formatting:Format numbers,dates,times and currency amounts according the conventions of chosen locale.
- Regular Expression:ICU's regular expressions fully support Unicode while providing very competitive performance.
- Bidi:support for handling containing a mixture of left or right(English) and right to left(Arbic or Hebrew) data.
- Text Boundaries:Locate the positions of word,sentences,paragraphs within a range of text, or identify locations that would be suitable for line wrapping when displying the text.
- and so on.
ICU库有很多功能,不过这里这关注了Code Page,即将文本数据与Unicode以及其他字符集或编码进行转换,如对其他功能感兴趣,可以观看官网https://icu.unicode.org/。
二、安装ICU4C
本文统一环境:window10 x64,IDE是VS2019。
可以下载编译好的动态库或者源码编译安装。
-
下载编译好的动态库
网址为:https://github.com/unicode-org/icu/releases/tag/release-71-1
选择icu4c-71_1-Win64-MSVC2019.zip以及icu4c-71_1-data-bin-l.zip ,这两个文件,前者是动态库,后者是ICU_DATA,字节序是小端,windows10 x64是小端。
-
源码编译
下载地址为:https://github.com/unicode-org/icu/archive/refs/tags/release-71-1.zip
解压后,进入目录icu4c/source/allinone,使用VS2019打开allione.sh,然后进行编译。
或者,使用命令行进行编译,具体可以参考官方,https://unicode-org.github.io/icu/userguide/icu4c/build.html#running-the-tests-from-the-windows-command-line-cmd。
三、使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #include <cstdlib> #include <cstdio> #include <string> #include <iostream> #include "unicode/putil.h" #include "unicode/udata.h" #include "unicode/ucnv.h" namespace { char * g_icu_data_ptr = nullptr ; void free_icu_data_ptr() { delete [] g_icu_data_ptr; std::cout << "free icu data." << std::endl; } } bool init_icu() { FILE * inf = fopen ( "D:\\workspace\\KeyWords\\commondata\\icudt71l.dat" , "rb" ); if (!inf) return false ; std::shared_ptr< FILE > p_inf(inf, fclose ); fseek (inf, 0, SEEK_END); size_t size = ftell (p_inf.get()); rewind (p_inf.get()); //分配内存,用于存储icu data char * icu_data_ptr = new char [size]; if ( fread (icu_data_ptr, 1, size, inf) != size) { delete [] icu_data_ptr; icu_data_ptr = nullptr ; return false ; } //main函数退出时调用,用于释放存储icu data的内存,该数据只能在程序结束后释放,否则后续使用icu方法时会出错。 atexit (free_icu_data_ptr); UErrorCode err = U_ZERO_ERROR; udata_setCommonData( reinterpret_cast < void *>(icu_data_ptr), &err); // Never try to load ICU data from files. udata_setFileAccess(UDATA_ONLY_PACKAGES, &err); return err == U_ZERO_ERROR; } int main() { //初始化ICU DATA,本列中是必须,否则转换错误。 if (!init_icu()) return -1; std::string word = "好啊" ; UErrorCode status{ U_ZERO_ERROR }; size_t enough_size = 4*word.size(); std::shared_ptr< char > sp_buf( new char [enough_size], []( char * p) { delete [] p; p = nullptr ;}); int len = ucnv_convert( "UTF8" , NULL, sp_buf.get(), enough_size, word.c_str(), word.size(), &status); if (U_FAILURE(status)) { return -1; } //输出16进制 std::cout << std::hex; for (int32_t i = 0; i < len; ++i) { std::cout << int ((uint8_t)sp_buf.get()[i]) << " " ; } return 0; } |
1 因为是在windows系统下,std::string word = "好啊"; 2 编译器会翻译成gbk编码,即"\xba\xc3\xb0\xa1"。 3 4 main函数中调用ucnv_convert("UTF8",NULL,...)方法,将word转成 5 UTF8编码的字节序。 6 7 最终打印出来的16进制为: 8 e5 a5 bd e5 95 8a 9 刚好是"好啊"的UTF8编码序列。
四、结语
ICU还有很多强大的功能,对Unicode的支持非常全面,这里只是列举了编码转换的方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?