16. ICU库安装与使用指南

1 安装

ICU(International Components for Unicode)是一个跨平台的C++库,用于处理Unicode字符和文本字符串的各种操作。

ICU的主要功能包括:

  • 字符串操作:ICU库提供了丰富的字符串操作功能,包括字符串分割、子字符串查找和替换、大小写转换等。
  • 格式化和国际化:ICU库使得格式化和解析具有国际化能力的日期、货币、数字和时区等信息变得非常容易。
  • 排序和比较:ICU库提供了丰富的字符和字符串排序和比较功能,支持多语言和多种排序规则。
  • 正则表达式:ICU库还提供了正则表达式功能,可以进行Unicode字符集的正则匹配和替换。
  • 文本转换:ICU库提供了多种字符集和文本格式的转换功能,如Unicode、UTF-8、UTF-16等编码格式之间的转换。

而安装ICU库最简单的方式就是使用vcpkg包管理,使用方法请参考这篇文章: vcpkg

然后使用命令直接安装即可:

.\vcpkg.exe install icu:x64-windows

或者:

.\vcpkg.exe install icu

或者你也可以去github自己下载:unicode-org/icu

image.png

然后选择自己合适的版本进行下载:

image.png

下载解压后,就会有下面两个头文件夹与库文件夹:

image.png

复制到你的项目中,包含它,链接静态库,这些基本操作就不再赘述了。

推荐使用第一种方法,简单省事。

2 编码转换

想要在C++中操作utf-8编码是一件非常麻烦的事情,但现在大部分应用程序、包括网站都使用的utf-8编码,所以有时候想要处理这些数据就会比较麻烦。

比如我们电脑一般使用的都是GBK编码,而C++默认使用本地编码,也就是GBK编码,也就导致了当你用C++处理UTF-8编码的文本时经常出现乱码的情况。

这个时候我们就需要将其转换为本地GBK编码,再进行操作,也就是编码转换

下面转换操作只用到了一个头文件:

#include <unicode/ucnv.h>

函数只用到了一个:

  • ucnv_convert:编码转换

ucnv_convert函数的参数比较多:

  • 第一个参数:你想要转换为的目标编码
  • 第二个参数:源字符串编码
  • 第三个参数:存放转换结果的缓存区
  • 第四个参数:缓存区大小
  • 第五个参数:源字符串
  • 第六个参数:源字符串的大小
  • 第七个参数:返回的错误信息

2.1 gbk 转 utf-8

std::string gbk_to_utf8(const std::string&gbk) {
    UErrorCode error = U_ZERO_ERROR;
    std::string u8str((gbk.size()+1) * 2, '\0'); //预留足够大的空间
    ucnv_convert("UTF-8", "GBK", (char*)u8str.c_str(), (gbk.size() + 1) * 2, gbk.c_str(), gbk.size(), &error);
    if (U_FAILURE(error)) {
        throw "Failed to convert string";
    }
    return u8str;
}

2.2 utf-8 转 gbk

std::string utf8_to_gbk(const std::string& utf8) {
    UErrorCode error = U_ZERO_ERROR;
    std::string gbkstr((utf8.size() + 1) * 3, '\0'); //预留足够大的空间
    ucnv_convert("GBK", "UTF-8", (char*)gbkstr.c_str(), (utf8.size() + 1) * 3, utf8.c_str(), utf8.size(), &error);
    if (U_FAILURE(error)) {
        throw "Failed to convert string";
    }
    return gbkstr;
}

2.3 gbk 转 utf-16(宽字符)

std::wstring gbk_to_utf16(const std::string& gbk) {
    UErrorCode error = U_ZERO_ERROR;
    std::wstring wstr((gbk.size() + 1) * 2, '\0'); //预留足够大的空间
    ucnv_convert("UTF-16", "GBK", (char*)wstr.c_str(), (wstr.size() + 1) * 2, gbk.c_str(), gbk.size(), &error);
    if (U_FAILURE(error)) {
        throw "Failed to convert string";
    }
    return wstr;
}

2.4 utf16 转 gbk

std::string utf16_to_gbk(const std::wstring& utf16) {
    UErrorCode error = U_ZERO_ERROR;
    std::string gbkstr((utf16.size() + 1) * 2, '\0'); //预留足够大的空间
    ucnv_convert("GBK", "UTF-16", (char*)gbkstr.c_str(), (gbkstr.size() + 1) * 2, (char*)utf16.c_str(), utf16.size()*2, &error);
    if (U_FAILURE(error)) {
        throw "Failed to convert string";
    }
    return gbkstr;
}

2.5 utf-8 转 utf16

std::wstring utf8_to_utf16(const std::string& utf8) {
    UErrorCode error = U_ZERO_ERROR;
    std::wstring wstr(utf8.size()+1, '\0'); //预留足够大的空间
    ucnv_convert("UTF-16", "UTF-8", (char*)wstr.c_str(), (wstr.size()+1)*2, utf8.c_str(), utf8.size(), &error);
    if (U_FAILURE(error)) {
        throw "Failed to convert string";
    }
    return wstr;
}