Ubuntu下C++使用icu库检测字符编码

Ubuntu下C++使用icu库检测字符编码。需先安装libicu-dev库:

sudo apt install libicu-dev

  

C++代码如下:

//g++ -o x x.cpp -licuuc -licui18n
#include <stdio.h>
#include <string.h>

#include <unicode/ucnv.h>
#include <unicode/utypes.h>
#include <unicode/ucsdet.h>

#define BUF_MAX     4096

/*
 * data,    传入参数, 需要探测的字符串
 * len,     传入参数, 探测字符串长度
 * detected  传出参数, 探测的最有可能的字符编码名称, 调用者需要释放该字段
**/
bool detectTextEncoding(const char *data, int32_t len, char **detected) {
    UCharsetDetector *csd;
    const UCharsetMatch **csm;
    int32_t match, matchCount = 0;

    UErrorCode status = U_ZERO_ERROR;

    csd = ucsdet_open(&status);
    if (status != U_ZERO_ERROR)
        return false;

    ucsdet_setText(csd, data, len, &status);
    if (status != U_ZERO_ERROR)
        return false;

    csm = ucsdet_detectAll(csd, &matchCount, &status);
    if (status != U_ZERO_ERROR)
        return false;

#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 = "**";

        printf("%s (%s) %d\n", name, lang, confidence);
    }
#endif

    if (matchCount > 0) {
        *detected = strdup(ucsdet_getName(csm[0], &status)); //分配了内存, 需要释放
        if (status != U_ZERO_ERROR)
            return false;
    }

    printf("charset = %s\n", *detected);

    ucsdet_close(csd);
    return true;
}

/*
 * toConverterName,      转换后的字符编码
 * fromConverterName,    转换前的字符编码
 * target,               存储转换后的字符串, 传出参数
 * targetCapacity,       存储容量,target的大小
 * source,              需要转换的字符串
 * sourceLength,         source的大小
**/
int 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;
}

int main(int argc, char **argv) {
    if (argc <= 1) {
        printf("Usage: %s [filename]...\n", argv[0]);
        return -1;
    }

    FILE *file;
    char *filename = argv[1];

    file = fopen(filename, "rb");
    if (file == NULL) {
        printf("Cannot open file \"%s\"\n\n", filename);
        return -1;
    }

    int len = 0;
    char *detected = NULL;

    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(buffer, len, &detected)) //编码探测
                break;
        }

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

        printf("%s", target); //打印出转换的文件的字符串

        if (len < BUF_MAX)
            break;
    }

    delete[] buffer;
    delete[] target;
    delete[] detected;
    fclose(file);

    return 0;
}

  测试一下,正常检测出了当前文件编码:

原文地址:https://www.cnblogs.com/areful/p/12198062.html

时间: 2024-07-30 09:39:38

Ubuntu下C++使用icu库检测字符编码的相关文章

C++链接库的使用,二维向量,三维向量,Ubuntu下C++测试向量库

1.#include<iostream> using namespace std; int main() { cout<<"Hello Woeld"<<endl; return 0; } 2.vector.cxx #include<iostream> int main() {int k; char x; cout<<"请输入向量的维度:"<<endl; cin>>k; vector

Ubuntu下C++基于eigen库SVD矩阵奇异值分解效率分析

在优化求解问题中,经常要用到矩阵奇异值的SVD分解. 奇异值分解 (singularvalue decomposition,SVD)是一种可靠地正交矩阵分解法,它比QR分解法要花上近十倍的计算时间. 使用SVD分解法的用途是解最小平方误差法和数据压缩. 在Ubuntu下基于eigen C++库测试了eigen SVD算法的性能,即SVD求解最小二乘/伪逆,代码如下: //compile: g++ test_svd.cpp #include <iostream> #include <Eig

ubuntu下安装 openssl 开发库

ubuntu下安装 openssl 开发库 检查是否已安装openssl: sudo apt-get install openssl 如果已安装执行以下操作:sudo apt-get install libssl-devsudo apt-get install libssl0.9.8 Ubuntu 下安装 GTK+ 开发库sudo apt-get install libgtk2.0-dev

ubuntu下python安装第三方库(library)的简易方法

安装个easy_install工具 sudo apt-get install python-setuptools 然后sudo就OK了 比如Ubuntu下Python读写excel库 sudo easy_install xlrd sudo easy_install xlwt sudo easy_install xlutils 使用: import xlrd import xlwt import xlutils

Android中检测字符编码(GB2312,ASCII,UTF8,UNICODE,TOTAL——ENCODINGS)方法(一)

package com.android.filebrowser; import java.io.*; import java.net.*; public class FileEncodingDetect { static final int GB2312 = 0; static final int ASCII = 1; static final int UTF8 = 2; static final int UNICODE = 3; //static final int GBK = 4; //st

Android中检测字符编码(GB2312,ASCII,UTF8,UNICODE,TOTAL——ENCODINGS)方法(二)

Intent intent = getIntent(); String contentUri = null; Uri uri =null; if (intent.getData() != null) { uri = intent.getData(); contentUri = "file".equals(uri.getScheme()) ? FileContentProvider.BASE_URI + uri.getEncodedPath() : uri.toString(); Str

使用c++11标准库转换字符编码

转自:http://www.cnblogs.com/LinuxHunter/archive/2013/01/06/2848293.html #include <stdio.h> #include <locale> #include <codecvt> const std::string ws2s( const std::wstring& src ) { std::locale sys_locale(""); const wchar_t* da

python标准库之字符编码详解

codesc官方地址:https://docs.python.org/2/library/codecs.html 相关帮助:http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html #python标准库(英文地址:)http://www.ask3.cn/ebook/docspy3zh/library/index.html unicode入门: cpython2.xz支持2种类型字符串处理文本数据,老式的str实例使用单个8位字节表示字

ubuntu 下安装32位库 ia32-libs方法

这两天在整Linux系统,要配置JDK,SDK环境,但是SDK配置使用的时候,提示没有权限. 需要安装32位库来解决,还有就是在修改文件的时候提示不能修改.唉...反正就是没有办法正常操作啦 后来根据查找的情况的是因为没有安装32位库原因导致的就开始查找如何,普遍的方法都是用命令安装. 但是提示文件依赖性限制,不能安装. 后来又根据几篇网络文章终于找到方法. 下面就分享出来,以做记录 1.更改权限,在root账户下操作 sudo -i cd /etc/apt/sources.list.d ech