centos下ICU4C字符集检测和转换,C++版本

本文介绍了ICU4C库的安装与使用方法,通过一个示例程序详细讲解了如何利用ICU4C进行文本编码检测及转换为UTF-8编码。文章包括ICU4C的简介、安装步骤、代码实现及编译命令等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.ICUUC简介

ICU4C是ICU在C/C++平台下的版本, ICU(International Component for Unicode)是基于”IBM公共许可证”的,与开源组织合作研究的, 用于支持软件国际化的开源项目。ICU4C提供了C/C++平台强大的国际化开发能力,软件开发者几乎可以使用ICU4C解决任何国际化的问题,根据各地的风俗和语言习惯,实现对数字、货币、时间、日期、和消息的格式化、解析,对字符串进行大小写转换、整理、搜索和排序等功能,必须一提的是,ICU4C提供了强大的BIDI算法,对阿拉伯语等BIDI语言提供了完善的支持。

2.安装

2.1 在http://www.icu-project.org/download/4.2.html下载ICU4C库,我下载的是icu4c-49_1_2-src.tgz。
2.2 执行如下命令,安装成功:

tar -zxvf icu4c-49_1_2-src.tgz 
cd icu/source
./configure
make
make install

3.代码

3.1 myicu.h

#ifndef _MYICU_H_
#define _MYICU_H_
#include "unicode/utypes.h"
#include "unicode/ucsdet.h"
#include "unicode/ucnv.h"
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;

#define BUF_MAX     4096 
class MyIcu{
public:
    MyIcu(const char* filename);
    bool detectTextEncoding();
    bool convertoUtf8();
    int convert(const char *toConverterName, const char *fromConverterName,  
            char *target, int32_t targetCapacity, const char *source, int32_t sourceLength);
    ~MyIcu();
private:
    const char* m_filename;
    FILE* file;
    char* detected;
};
#endif //_MYICU_H_

3.2 myicu.cpp

#include "myicu.h"
const int BUFFSIZE=8192;
MyIcu::MyIcu(const char* filename):m_filename(filename){
}


MyIcu::~MyIcu(){
    fclose(file);
    delete [] detected;  
}
bool MyIcu::detectTextEncoding(){
    UCharsetDetector* csd;
    const UCharsetMatch **csm;
    UErrorCode status = U_ZERO_ERROR;
    char buffer[BUFFSIZE];
    int inputLength,match, matchCount = 0;
    file = fopen(m_filename, "rb");
    if (file == NULL) {
        cout<<"open file error"<<endl;
        return 0;
    }
    inputLength = (int32_t) fread(buffer, 1, BUFFSIZE, file);


    csd = ucsdet_open(&status);
    ucsdet_setText(csd, buffer,inputLength, &status);
    csm = ucsdet_detectAll(csd, &matchCount, &status);
    if(csm == NULL){
        ucsdet_close(csd);
        return 0;
    }
    detected = new char[128];
#if 0
    for(match = 0; match < matchCount; match += 1) {
        const char *name = ucsdet_getName(csm[match], &status);         
        const char *lang = ucsdet_getLanguage(csm[match], &status);
        int32_t confidence = ucsdet_getConfidence(csm[match], &status);

        if (lang == NULL || strlen(lang) == 0) {
            lang = "**";
        }
        cout<<name <<"("<<lang<<")"<<confidence<<endl;
    }
#endif
        if(matchCount > 0)  
        {  
            detected = strdup(ucsdet_getName(csm[0], &status)); //分配了内存, 需要释放  
            if(status != U_ZERO_ERROR)  
            return false;  
        }  
        cout<<"charset = "<<detected<<endl;
        ucsdet_close(csd);
        return 1;
}


bool MyIcu::convertoUtf8(){
     file = fopen(m_filename, "rb");  
    if(file == NULL)   
    {  
        cout<<"open file error"<<endl;
        return 0;  
    }     

    int len = 0;  
    //char *detected;  

    char *buffer = new char[BUF_MAX];  
    char *target = new char[BUF_MAX * 2];  

    while(true)  
    {  
        memset(buffer, 0, BUF_MAX);  
        memset(target, 0, BUF_MAX * 2);  

        len = (int32_t)fread(buffer, sizeof(char), BUF_MAX, file);  

        if(detected == NULL)  
        {  
            if(!detectTextEncoding()) //编码探测  
                break;  
        }  

        //转换为utf8字符编码  
        if(convert("UTF-8", detected, target, BUF_MAX * 2, (const char*)buffer, len) != U_ZERO_ERROR)  
        {  
            cout<<"ucnv_convert error"<<endl;
            break;  
        }  

        cout<<target<<endl;//打印出转换的文件的字符串  

        if(len < BUF_MAX)  
            break;  
    }  

    delete [] buffer;  
    delete [] target;  

    return 1;
}



int MyIcu::convert(const char *toConverterName, const char *fromConverterName,  
            char *target, int32_t targetCapacity, const char *source, int32_t sourceLength){

                 UErrorCode error = U_ZERO_ERROR;  
                ucnv_convert(toConverterName, fromConverterName, target, targetCapacity,
                    source, sourceLength, &error);  
                  return error;
}

3.3 main.cpp

#include "myicu.h"
#include <string>

#include <cstdio>
#define BUF_MAX     4096


int main(){
    const char* filename = "123.txt";
    MyIcu myicu(filename);
    //char* buff = new char[126];
    bool flag = myicu.detectTextEncoding();
    if(!flag){
        std::cout<<"解析错误!"<<endl;
    }
    bool flag2 = myicu.convertoUtf8();
    if(!flag2){
        std::cout<<"转换错误!"<<endl;
    }
}

4编译

g++ -o target main.cpp myicu.cpp -licuuc -licui18n

如果找不到icuuc和icui18n动态库的话,执行如下命令:

vim /etc/ld.so.conf

将/usr/local/目录加进去,然后再

ldconfig

就行了。

你们可以试下自己准备的文件。

参考文档:
http://icu-project.org/apiref/icu4c/index.html

<think>我们遇到了编译错误:fatal error: unistr.h: No such file or directory 这个头文件属于ICU(International Components for Unicode)库的一部分,通常用于Unicode字符串处理。 根据引用[1]中的步骤,用户是在CentOS上编译xmap项目。因此,我们需要安装ICU的开发包。 解决方案: 1. 安装ICU开发包(提供unistr.h等头文件库) 在CentOS/RHEL系统上,包名为libicu-devel 2. 安装命令: sudo yum install libicu-devel 3. 安装后重新编译项目(按照引用[1]的步骤): cd xmap-master cmake -DRESPECT_INSTALL_PREFIX_CONFIG=ON -S . -B . make -j4 make install 4. 如果问题仍然存在,可能需要检查CMake是否找到了ICU库。可以尝试在cmake命令中指定ICU路径(但通常安装开发包后会自动找到)。 注意:如果是其他操作系统,安装的包名可能不同: Ubuntu/Debian: libicu-dev macOS (使用Homebrew): brew install icu4c Alpine Linux: icu-dev 如果系统同时存在多个版本ICU,可能需要通过设置环境变量来指定: export ICU_ROOT=/path/to/icu # 例如在macOS上可能是/usr/local/opt/icu4c 然后在CMake命令中指定: cmake -DICU_ROOT=$ICU_ROOT ... [其他参数] 原理:xmap项目依赖ICU库来处理Unicode字符串,缺少开发包会导致编译失败。 引用说明: 引用[1]提供了xmap在CentOS上的编译步骤,但未提及依赖库安装,因此我们需要补充。 相关问题: 1. 如何解决其他缺失的头文件(如utypes.h)? 2. 在非CentOS系统上如何安装ICU开发包? 3. CMake如何查找ICU库的位置?</think>### 解决编译错误:`fatal error: unistr.h: No such file or directory` 该错误表明您的系统缺少 ICU(International Components for Unicode)库的开发文件。`unistr.h` 是 ICU 库中用于 Unicode 字符串处理的关键头文件。以下是完整的解决方案: #### 1. **安装 ICU 开发包** 根据您的操作系统选择安装命令: ```bash # CentOS/RHEL(参考引用[1]环境) sudo yum install libicu-devel # Ubuntu/Debian sudo apt-get install libicu-dev # macOS(使用 Homebrew) brew install icu4c ``` #### 2. **验证 ICU 安装** 检查头文件是否存在: ```bash # 查找 unistr.h 路径 find /usr -name unistr.h 2>/dev/null # 正常应返回类似:/usr/include/unicode/unistr.h ``` #### 3. **重新编译项目** ```bash cd xmap-master # 清除 CMake 缓存(重要!) rm -rf CMakeCache.txt # 重新配置编译(参考引用[1]) cmake -DRESPECT_INSTALL_PREFIX_CONFIG=ON -S . -B . make -j4 sudo make install ``` #### 4. **特殊情况处理** 如果安装后仍报错: - **手动指定头文件路径**: ```bash # 查找 ICU 安装路径 icu-config --prefix # 通常为 /usr 或 /usr/local # 在 CMake 命令中添加包含路径 cmake -DCMAKE_CXX_FLAGS="-I/usr/include/unicode" ... ``` - **检查 ICU 版本兼容性**: ```bash # 查看已安装版本 pkg-config --modversion icu-uc ``` 若版本过低(<60),需升级 ICU: ```bash # CentOS 升级示例 sudo yum remove libicu-devel sudo yum install epel-release sudo yum install libicu-devel --enablerepo=epel ``` #### 5. **编译依赖原理** `unistr.h` 属于 ICUC++ Unicode API 组件[^1],提供: - Unicode 字符串规范化(Normalization) - 字符集转换(Charset Conversion) - 双向文本布局(Bidi Layout) 在文本处理工具(如 xmap)中用于正确处理多语言字符集[^3]。 > **注意**:类似引用[3]中的环境兼容性问题,若在 ARM 架构(如 M1 Mac)编译,需确认 ICU 是否支持跨架构编译。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值