由于项目中需要转换原生unicode到ascii的功能,本来想的用的是linux或者windows自带的宽字节转成窄字节的函数,但由于本身使用了apr_iconv库,所以直接使用库函数来解决。

期间碰到了库函数使用一直出错的问题,一个是对应name的字符集库文件,需要设置一下APR_ICONV1_PATH,参考链接:

https://www.cnblogs.com/chaohi/archive/2011/07/04/2097237.html

还有就是打印不出来outbuf中的东西。

然后参考链接:https://www.cnblogs.com/etangyushan/p/3753847.html找到了问题所在(下文中的红色部分)。

这里记录一下:

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\n", 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\n", inbuf, srclen, outbuf, outlen);int i = 0;for (i=0; i<strlen(outbuf); i++){printf("%x\n", 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\n", inbuf);/* 打印需要转换的字符串的长度 */printf("inlen=%d\n", *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\n", outbuf);//存放转换后outbuf剩余的空间printf("outlen=%d\n", *outlen);int i = 0;for (i=0; i<(outsize- (*outlen)); i++){//printf("%2c", outbuf[i]);printf("%x\n", 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\n", inbuf);/* 打印需要转换的字符串的长度 */printf("inlen=%d\n", *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\n", outbuf);//存放转换后outbuf剩余的空间printf("outlen=%d\n", *outlen);int i = 0;for (i=0; i<(outsize- (*outlen)); i++){//printf("%2c", outbuf[i]);printf("%x\n", 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\n", outbuf);size_t outsize = strlen(outbuf);size_t insize = 1024;char instr[1024] = {};unicode_to_utf8 (outbuf, &outsize, instr, &insize);printf ("print buf: %s\n", instr);return 0;
}

linux下c语言利用iconv函数实现utf-8转unicode相关推荐

  1. 关于Linux下C语言编程execvp函数的一个问题

    在实现linux管道命令的shell程序的时候,在主函数里面创建了两个子进程,l都调用了execvp函数来执行命令,但是很奇怪的是,当命令可以执行的时候,程序正常执行,子进程也是每次都正常退出,但是如 ...

  2. Linux下c语言文件读写函数总结

    1.FILE *fopen(const char *filename, const char *mode) "r" 打开一个用于读取的文件.该文件必须存在. "w&quo ...

  3. linux+下c语言编程项目,精通UNIX下C语言编程与项目实践

    cc -I  //include 目录 -L //静态库目录?动态也可以 -l //小写L,接静态库名称?动态也可以 -DXXX='"XXFF"' //-D直接定义宏 -c 只编译 ...

  4. 利用多线程实现linux下C语言的聊天室程序:

    转载:http://www.360doc.com/content/16/0421/11/478627_552531090.shtml 利用多线程实现linux下C语言的聊天室程序: 客户端代码: th ...

  5. linux父进程中显示子进程pid,请教linux下c语言函数fork父进程打印子进程的PID

    请教linux下c语言函数fork父进程打印子进程的PID 关注:296  答案:2  信息版本:手机版 解决时间 2019-01-14 04:55 雨不眠的下 2019-01-13 12:23 用于 ...

  6. c语言使用iconv函数实现字符编码转换

    c语言使用iconv函数实现字符编码转换 linux下提供了iconv库来实现字符编码转换,先介绍下命令行: iconv [-f encoding] [-t encoding] [inputfile ...

  7. Linux下C语言编程-进程的创建

    Linux下C语言编程-进程的创建 作者:hoyt 1.进程的概念 Linux操作系统是面向多用户的.在同一时间可以有许多用户向操作系统发出各种命令.那么操作系统是怎么实现多用户的环境呢?在现代的操作 ...

  8. 您知道Linux下C语言编程的一些注意事项吗_教育中国

    您知道Linux下C语言编程的一些注意事项吗_教育中国 云风的 BLOG: 一个 C 接口设计的问题 一个 C 接口设计的问题 C 语言在本质上,参数传递都是值传递.不像 Pascal 和 C++ 可 ...

  9. 关于Linux下C语言开发基础的实验内容。

    Linux下C语言开发基础实验内容 目录 1.Linux下C语言开发流程 2.vi,vim编辑器的使用 3.Gcc编译器的使用 总体选项: 警告选项: 4.GDB 基本命令的使用 5.Make 工程管 ...

最新文章

  1. 更新maven一直在更新_不更新app,就可以一直派单了?闪送政策早知道
  2. mysql 优化方法_Mysql的优化方法介绍
  3. PAT1006 换个格式输出整数
  4. CV_Sicong Liu
  5. 很火的仿soul交友盲盒1.0全开源源码
  6. Docker学习总结(56)——Docker-compose 基础知识温习
  7. MongoDB 在windows shell环境下的基本操作和命令的使用示例(五)
  8. win7便笺重启计算机后还有吗,Win7电脑关机后,记在便签小工具上的内容还在吗?...
  9. linux自己写摄像头驱动,详解linux 摄像头驱动编写
  10. dell重装系统后找不到无线网卡驱动
  11. 高级运维工程师证书_华为认证云运维高级工程师(HCIP-CDCO)
  12. SCS【1】今天开启单细胞之旅,述说单细胞测序的前世今生
  13. 老式计算机如何设置u盘启动,新旧主板BIOS设置U盘启动详细分析
  14. 三、EXCEL复制数字到txt文件,存在空格
  15. Json字符串的标准写法
  16. Cesium飞行效果
  17. 软件工程课程作业--UON
  18. go语言记录日志uber-go/zap/lumberjack的用法
  19. 如何删除顽固的 AVI 格式的影音文件
  20. 计算机网络隧道工程,隧道工程

热门文章

  1. C++ getline() 和 get()
  2. spark-jar冲突解决方案
  3. 深度学习在自然语言处理的应用(Version 0.76)
  4. Windows 通过 putty 连接 虚拟机下linux 问题
  5. (最优解)L1-028 判断素数 (10分)——17行代码AC
  6. mysql limit 和 offset用法
  7. c语言 输入若干字符串 用指针和一位数组 冒泡排序,C 语言作业 - 1 - 指针使用与冒泡排序...
  8. 深入了解计算机网络参考模型
  9. mysql 二进制转字符串_MySql字符转义 | 学步园
  10. Redhat系统下三种主要的软件包安装方法