icu 字符串编码探测及字符串编码转换实例

来源:互联网 发布:苹果手机画图软件 编辑:程序博客网 时间:2024/04/25 17:33

请大家确认是否安装icu库

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. #include <unicode/ucnv.h>  
  5. #include <unicode/utypes.h>  
  6. #include <unicode/ucsdet.h>  
  7.   
  8. #define BUF_MAX     4096  
  9.   
  10. /* 
  11.  * data,    传入参数, 需要探测的字符串 
  12.  * len,     传入参数, 探测字符串长度 
  13.  * detected  传出参数, 探测的最有可能的字符编码名称, 调用者需要释放该字段 
  14. **/  
  15. bool detectTextEncoding(const char *data, int32_t len, char **detected)  
  16. {  
  17.     UCharsetDetector* csd;  
  18.     const UCharsetMatch **csm;  
  19.     int32_t match, matchCount = 0;  
  20.   
  21.     UErrorCode status = U_ZERO_ERROR;  
  22.   
  23.     csd = ucsdet_open(&status);  
  24.     if(status != U_ZERO_ERROR)  
  25.         return false;  
  26.    
  27.     ucsdet_setText(csd, data, len, &status);  
  28.     if(status != U_ZERO_ERROR)  
  29.         return false;  
  30.   
  31.     csm = ucsdet_detectAll(csd, &matchCount, &status);  
  32.     if(status != U_ZERO_ERROR)  
  33.         return false;  
  34.   
  35. #if 0 //打印出探测的可能的编码  
  36.     for(match = 0; match < matchCount; match += 1)   
  37.     {  
  38.         const char *name = ucsdet_getName(csm[match], &status);  
  39.         const char *lang = ucsdet_getLanguage(csm[match], &status);  
  40.         int32_t confidence = ucsdet_getConfidence(csm[match], &status);  
  41.   
  42.         if (lang == NULL || strlen(lang) == 0)  
  43.                 lang = "**";  
  44.   
  45.         printf("%s (%s) %d\n", name, lang, confidence);  
  46.     }  
  47. #endif  
  48.   
  49.     if(matchCount > 0)  
  50.     {  
  51.         *detected = strdup(ucsdet_getName(csm[0], &status)); //分配了内存, 需要释放  
  52.         if(status != U_ZERO_ERROR)  
  53.             return false;  
  54.     }  
  55.   
  56.     printf("charset = %s\n", *detected);  
  57.   
  58.     ucsdet_close(csd);  
  59.     return true;  
  60. }  
  61.   
  62.   
  63. /* 
  64.  * toConverterName,      转换后的字符编码 
  65.  * fromConverterName,    转换前的字符编码 
  66.  * target,               存储转换后的字符串, 传出参数 
  67.  * targetCapacity,       存储容量,target的大小 
  68.  * source,              需要转换的字符串 
  69.  * sourceLength,         source的大小 
  70. **/  
  71. int convert(const char *toConverterName, const char *fromConverterName,  
  72.             char *target, int32_t targetCapacity, const char *source, int32_t sourceLength)  
  73. {  
  74.     UErrorCode error = U_ZERO_ERROR;  
  75.     ucnv_convert(toConverterName, fromConverterName, target, targetCapacity, source, sourceLength, &error);  
  76.   
  77.     return error;  
  78. }  
  79.   
  80. int main(int argc, char **argv)  
  81. {  
  82.     if(argc <= 1)   
  83.     {   
  84.         printf("Usage: %s [filename]...\n", argv[0]);  
  85.         return -1;   
  86.     }  
  87.   
  88.     FILE *file;  
  89.     char *filename = argv[1];  
  90.   
  91.     file = fopen(filename, "rb");  
  92.     if(file == NULL)   
  93.     {  
  94.         printf("Cannot open file \"%s\"\n\n", filename);  
  95.         return -1;  
  96.     }     
  97.   
  98.     int len = 0;  
  99.     char *detected = NULL;  
  100.   
  101.     char *buffer = new char[BUF_MAX];  
  102.     char *target = new char[BUF_MAX * 2];  
  103.   
  104.     while(true)  
  105.     {  
  106.         memset(buffer, 0, BUF_MAX);  
  107.         memset(target, 0, BUF_MAX * 2);  
  108.   
  109.         len = (int32_t)fread(buffer, sizeof(char), BUF_MAX, file);  
  110.           
  111.         if(detected == NULL)  
  112.         {  
  113.             if(!detectTextEncoding(buffer, len, &detected)) //编码探测  
  114.                 break;  
  115.         }  
  116.   
  117.         //转换为utf8字符编码  
  118.         if(convert("UTF-8", detected, target, BUF_MAX * 2, (const char*)buffer, len) != U_ZERO_ERROR)  
  119.         {  
  120.             printf("ucnv_convert error");  
  121.             break;  
  122.         }  
  123.   
  124.         printf("%s", target); //打印出转换的文件的字符串  
  125.   
  126.         if(len < BUF_MAX)  
  127.             break;  
  128.     }  
  129.   
  130.     delete [] buffer;  
  131.     delete [] target;  
  132.     delete [] detected;  
  133.     fclose(file);  
  134.   
  135.     return 0;  
  136. }