zoukankan      html  css  js  c++  java
  • linux下c语言利用iconv函数实现utf-8转unicode

    iconv是linux下的编码转换的工具,它提供命令行的使用和函数接口支持

    man手册iconv命令用法如下:

    iconv -f encoding -t encoding inputfile

    有如下选项可用:

    输入/输出格式规范:
    -f, --from-code=名称 原始文本编码
    -t, --to-code=名称 输出编码

    信息:

    -l, --list 列举所有已知的字符集

    输出控制:

    -c 从输出中忽略无效的字符
    -o, --output=FILE 输出文件
    -s, --silent 关闭警告
    --verbose 打印进度信息

    示例:下面的命令是将一个utf8编码的文件转换为一个unicode编码的文件

    iconv -f utf-8 -t unicode utf8file.txt> unicodefile.txt

    iconv函数族的头文件是iconv.h,使用前需包含之。

    #include <iconv.h>

    iconv函数族有三个函数,原型如下:

    iconv_t iconv_open(const char *tocode, const char *fromcode);

    此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。

    size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);

    此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。 

    注意:inbuf和outbuf都必须是有存储空间的不能定义为常量,如:char *inbuf = "abc" 或者是char *outbuf = "123"这样定义都是错误的。另外inbuf,inbytesleft,outbuf,outbytesleft这几个参数在使用过程中都会改变,最好是先保存一下原值,然后再使用

    int iconv_close(iconv_t cd);

    此函数用于关闭转换句柄,释放资源。

    基本使用举例:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iconv.h>
    
    int main(int argc, char **argv)
    {
      /* 目的编码, TRANSLIT:遇到无法转换的字符就找相近字符替换
       *          IGNORE  :遇到无法转换字符跳过*/
      //char *encTo = "UNICODE//TRANSLIT";
      char *encTo = "UNICODE//IGNORE";
      /* 源编码 */
      char *encFrom = "UTF-8";
    
      /* 获得转换句柄
       *@param encTo 目标编码方式
       *@param encFrom 源编码方式
       *
       * */
      iconv_t cd = iconv_open (encTo, encFrom);
      if (cd == (iconv_t)-1)
      {
          perror ("iconv_open");
      }
    
      /* 需要转换的字符串 */
      char inbuf[1024] = "abcdef哈哈哈哈行"; 
      size_t srclen = strlen (inbuf);
      /* 打印需要转换的字符串的长度 */
      printf("srclen=%d
    ", srclen);
    
      /* 存放转换后的字符串 */
      size_t outlen = 1024;
      char outbuf[outlen];
      memset (outbuf, 0, outlen);
    
      /* 由于iconv()函数会修改指针,所以要保存源指针 */
      char *srcstart = inbuf;
      char *tempoutbuf = outbuf;
    
      /* 进行转换
       *@param cd iconv_open()产生的句柄
       *@param srcstart 需要转换的字符串
       *@param srclen 存放还有多少字符没有转换
       *@param tempoutbuf 存放转换后的字符串
       *@param outlen 存放转换后,tempoutbuf剩余的空间
       *
       * */
      size_t ret = iconv (cd, &srcstart, &srclen, &tempoutbuf, &outlen);
      if (ret == -1)
      {
          perror ("iconv");
      }
      printf ("inbuf=%s, srclen=%d, outbuf=%s, outlen=%d
    ", inbuf, srclen, outbuf, outlen);
      int i = 0;
      for (i=0; i<strlen(outbuf); i++)
      {
          printf("%x
    ", outbuf[i]);
      }
    /* 关闭句柄 */
      iconv_close (cd);
    
      return 0;
    }

     下面做了一下函数的封装:

    /*
     * =====================================================================================
     *
     *       Filename:  iconv.c
     *
     *    Description:  j
     *
     *        Version:  1.0
     *        Created:  08/05/2015 05:51:47 PM
     *       Revision:  none
     *       Compiler:  gcc
     *
     *         Author:  YOUR NAME (), 
     *   Organization:  
     *
     * =====================================================================================
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    #include <iconv.h>
    bool unicode_to_utf8 (char *inbuf, size_t *inlen, char *outbuf, size_t *outlen)
    {
      /* 目的编码, TRANSLIT:遇到无法转换的字符就找相近字符替换
       *           IGNORE :遇到无法转换字符跳过*/
      char *encTo = "UTF-8//IGNORE";
    /* 源编码 */
      char *encFrom = "UNICODE";
    
      /* 获得转换句柄
       *@param encTo 目标编码方式
       *@param encFrom 源编码方式
       *
       * */
      iconv_t cd = iconv_open (encTo, encFrom);
      if (cd == (iconv_t)-1)
      {
         perror ("iconv_open");
      }
    
      /* 需要转换的字符串 */
      printf("inbuf=%s
    ", inbuf);
    
      /* 打印需要转换的字符串的长度 */
      printf("inlen=%d
    ", *inlen);
    
    
      /* 由于iconv()函数会修改指针,所以要保存源指针 */
      char *tmpin = inbuf;
      char *tmpout = outbuf;
      size_t insize = *inlen;
      size_t outsize = *outlen;
    
      /* 进行转换
       *@param cd iconv_open()产生的句柄
       *@param srcstart 需要转换的字符串
       *@param inlen 存放还有多少字符没有转换
       *@param tempoutbuf 存放转换后的字符串
       *@param outlen 存放转换后,tempoutbuf剩余的空间
       *
       * */
      size_t ret = iconv (cd, &tmpin, inlen, &tmpout, outlen);
      if (ret == -1)
      {
         perror ("iconv");
      }
    
      /* 存放转换后的字符串 */
      printf("outbuf=%s
    ", outbuf);
    
      //存放转换后outbuf剩余的空间
      printf("outlen=%d
    ", *outlen);
    
      int i = 0;
    
      for (i=0; i<(outsize- (*outlen)); i++)
      {
         //printf("%2c", outbuf[i]);
         printf("%x
    ", outbuf[i]);
      }
    
      /* 关闭句柄 */
      iconv_close (cd);
    
      return 0;
    }
    
    bool utf8_to_unicode (char *inbuf, size_t *inlen, char *outbuf, size_t *outlen)
    {
    
      /* 目的编码, TRANSLIT:遇到无法转换的字符就找相近字符替换
       *           IGNORE :遇到无法转换字符跳过*/
      char *encTo = "UNICODE//IGNORE";
      /* 源编码 */
      char *encFrom = "UTF-8";
    
      /* 获得转换句柄
       *@param encTo 目标编码方式
       *@param encFrom 源编码方式
       *
       * */
      iconv_t cd = iconv_open (encTo, encFrom);
      if (cd == (iconv_t)-1)
      {
          perror ("iconv_open");
      }
    
      /* 需要转换的字符串 */
      printf("inbuf=%s
    ", inbuf);
    
      /* 打印需要转换的字符串的长度 */
      printf("inlen=%d
    ", *inlen);
    
      /* 由于iconv()函数会修改指针,所以要保存源指针 */
      char *tmpin = inbuf;
      char *tmpout = outbuf;
      size_t insize = *inlen;
      size_t outsize = *outlen;
    
      /* 进行转换
       *@param cd iconv_open()产生的句柄
       *@param srcstart 需要转换的字符串
       *@param inlen 存放还有多少字符没有转换
       *@param tempoutbuf 存放转换后的字符串
       *@param outlen 存放转换后,tempoutbuf剩余的空间
       *
       * */
      size_t ret = iconv (cd, &tmpin, inlen, &tmpout, outlen);
      if (ret == -1)
      {
         perror ("iconv");
      }
    
      /* 存放转换后的字符串 */
      printf("outbuf=%s
    ", outbuf);
    
      //存放转换后outbuf剩余的空间
      printf("outlen=%d
    ", *outlen);
    
      int i = 0;
    
      for (i=0; i<(outsize- (*outlen)); i++)
      {
         //printf("%2c", outbuf[i]);
         printf("%x
    ", outbuf[i]);
      }
    
      /* 关闭句柄 */
      iconv_close (cd);
    
      return 0;
    }
    
    int main ()
    {
      /* 需要转换的字符串 */
      //char inbuf[1024] = "abcdef哈哈哈哈行"; 
      char *text = "";    
        
      char inbuf[1024] = {};
      strcpy (inbuf, text);
      size_t inlen = strlen (inbuf);
    
      /* 存放转换后的字符串 */
      char outbuf[1024] = {};
      size_t outlen = 1024;
    
      utf8_to_unicode (inbuf, &inlen, outbuf, &outlen);
      printf ("print outbuf: %s
    ", outbuf);
    
      size_t outsize = strlen(outbuf);
      size_t insize = 1024;
      char instr[1024] = {};
      unicode_to_utf8 (outbuf, &outsize, instr, &insize);
      printf ("print buf: %s
    ", instr);
      return 0;
    }
  • 相关阅读:
    leetcode1161
    leetcode1160
    校招真题练习034 倒水(贝壳)
    校招真题练习033 音乐列表(贝壳)
    校招真题练习032 连续相同字符串(头条)
    校招真题练习031 三支球队比分(头条)
    leetcode1144
    ArrayQueue(队列)
    LinkQueue(链队)
    快速幂
  • 原文地址:https://www.cnblogs.com/etangyushan/p/3753847.html
Copyright © 2011-2022 走看看