转自:http://www.linuxdiyf.com/viewarticle.php?id=45164

在Linux上进行编码转换时,既可以利用iconv函数族编程实现,也可以利用iconv命令来实现(针对文件进行转换)

一、利用iconv函数族进行编码转换

iconv函数族的头文件是iconv.h

使用前需包含之:#include

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

(1) iconv_open()

函数原型:

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

函数功能:

该函数分配一个编码转换句柄

参数:

1> tocode是目标编码

2> fromcode是原编码

(具体可以使用的编码方案可以百度查找)

支持的内码包括:Unicode相关编码,如UTF-8、UTF-16等等;各国采用的ANSI编码,其中包括GB2312、BIG5等中文编码方式。

返回值:

调用成功,则该函数返回一个转换句柄,供以下两个函数使用;

调用失败,返回-1,并且设置errno

可能的错误类型:

EINVAL The  conversion  from fromcode to tocode is not supported by the implementation.

(2) iconv()

函数功能:进行实际的编码转换

函数原型:

size_t iconv(iconv_t cd,

char **inbuf, size_t *inbytesleft,

char **outbuf, size_t *outbytesleft);

参数介绍:

1> cd是方法iconv_open()调用返回的转码句柄;

2> inbuf指向需要转码的缓冲区;

3> inbytesleft是inbuf所保存的需要转码的字节数;

4> outbuf存放转码结果;

5> outbytesleft存放outbuf空间的大小。

(不足之处:由于没有办法获取转换之后需要的内存大小,所以会造成内存空间的浪费!)

返回值:

调用成功,返回转换的字节数(不可逆转调用的字节数,可逆转调用的字节数不包括在内)

调用失败,返回-1,并设置相应的errno。

注意:

iconv()是逐步扫描inbuf,每转换一个字符,就增加inbuf,减少inbytesleft,并将结果存入outbuf,结果字节数存入outbytesleft

常见的三种情况:

情况一: inbuf不为空,而且*inbuf也不为空

此时,进行正常的编码转换

遇到下列情况将停止扫描并返回:

(1)inbuf中碰到非法的多字节序

这种状况下,会设置errno为EILSEQ,并返回-1;

(2)inbuf字节被完全转换

这种状况下,返回转换的字节数

(3)inbuf中碰到不完整的多字节序

这种状况下,设置errno为EINVAL,并返回-1;

(4)outbuf中没有足够的空间以进行下一次的字符转换

这种状况下,设置errno为E2BIG,并返回-1;

情况二:inbuf == NULL,或者*inbuf == NULL;但outbuf != NULL,且*outbuf != NULL

iconv会设置转换状态为初始状态,并保存转换序列到*outbuf。如果outbuf空间不足,errno会设置为E2BIG,返回(size_t) (-1);

情况三:INBUF == NULL,或者*inbuf == NULL; 并且outbuf == NULL,*out == NULL

iconv设置转换状态为初始状态

(3) iconv_close()

函数原型:

int iconv_close(iconv_t cd);

函数功能:

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

示例代码:

封装一个转换类型:

class CCodeConverter

{

public:

CCodeConverter(const char * fromCode, const char * toCode)

{

hCodeConverter=iconv_open(toCode, fromCode);

}

~CCodeConverter()

{

iconv_close(hCodeConverter);

}

//进行转换

int convert(char * srcBuf, int srcLen, char * destBuf, int destLen)

{

//返回转换的字符个数

int nConv=iconv(hCodeConverter, &srcBuf, (size_t *)&srcLen, &destBuf, (size_t *)&destLen);

//如果错误,则获取错误码

nErr=errno;

return nConv;

}

//获取错误信息

int getErrInfo()

{

switch(nErr)

{

case E2BIG:

{

printf("errno:E2BGI(OutBuf空间不够)\n");

break;

}

case EILSEQ:

{

printf("errno:EILSEQ(InBuf多字节序无效)\n");

break;

}

case EINVAL:

{

printf("errno:EINVAL(有残留的字节未转换)\n");

break;

}

default:

break;

}

return nErr;

}

private:

//转换句柄

iconv_t hCodeConverter;

int nErr;

};

以utf-8转为utf-16为例

int main()

{

int srcLen=12;

char * srcBuf=new char[srcLen];

memset(srcBuf, 0, srcLen);

strcpy(srcBuf, "BaiSe");

int destLen=2*srcLen;

char * destBuf=new char[destLen];

memset(destBuf, 0, destLen);

CCodeConverter cv=CCodeConverter("utf-8", "utf-16");

int nRet=cv.convert(srcBuf, srcLen, destBuf, destLen);

if(nRet<0)

{

cv.getErrInfo();

return -1;

}

printf("转换成功\n");

}调试,查看内存,destBuf内容如下:

(gdb) print destBuf

$1 = 0x804b018 "\377\376B"

(gdb) print destBuf+1

$2 = 0x804b019 "\376B"

(gdb) print destBuf+2

$3 = 0x804b01a "B"

(gdb) print destBuf+3

$4 = 0x804b01b ""

(gdb) print destBuf+4

$5 = 0x804b01c "a"

(gdb) print destBuf+5

$6 = 0x804b01d ""

(gdb) print destBuf+6

$7 = 0x804b01e "i"

问题:不明白为什么前面有"\377\376",是用来标识编码类型的么?

二、iconv命令

iconv命令用于转换指定文件的编码,默认输出到标准输出设备,亦可指定输出文件。

用法: iconv [选项...] [文件...]

有如下选项可用:

输入/输出格式规范:

-f, --from-code=名称 原始文本编码

-t, --to-code=名称 输出编码信息:

-l, --list 列举所有已知的字符集输出控制:

-c 从输出中忽略无效的字符

-o, --output=FILE 输出文件

-s, --silent 关闭警告

--verbose 打印进度信息

-?, --help 给出该系统求助列表

--usage 给出简要的用法信息

-V, --version 打印程序版本号

例子:

iconv -f utf-8 -t gb2312 aaa.txt >bbb.txt

这个命令读取aaa.txt文件,从utf-8编码转换为gb2312编码,其输出定向到bbb.txt文件。

linux中iconv函数,Linux下编码转换(iconv函数族)相关推荐

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

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

  2. linux中dup2函数,Linux 下的 dup 和 dup2 函数简介

    dup 和 dup2 都可以用来复制一个现存的文件描述符.经常用来重新定向进程的 STDIN, STDOUT, STDERR. dup 函数 dup 函数定义在 中,函数原形为: int dup ( ...

  3. Linux中gsub函数,Linux中awk下 gsub函数用法

    一.遇到的问题: 问题:echo "a b c 2011-11-22 a:d" | awk '$4=gsub(/-/,"",$4)'为啥 输出后 2011-11 ...

  4. linux中execvp函数,Linux shell的实现——execvp

    一.类Linux(包括Android)操作系统elf文件执行过程 从上边分析,我们知道:Linux支持的标准可执行文件格式为elf,Linux内核会对该格式文件进行解析并执行.而这个过程最重要的就是e ...

  5. linux中creat-file函数,Linux应用程序-文件编程-file_creat()函数的问题

    * **系统调用:创建一个文件 **函数原型:int creat(const char *filename,mode_t mode); **参数:filename->要创建的文件名(包含路径,缺 ...

  6. c语言linux下可用函数,[原创]linux下编码转换问题,C语言实现,使用iconv函数族68...

    [原创]linux下编码转换问题,C语言实现,使用iconv函数族68 (2012-07-30 02:49:00) 标签: linux 68 c语言 杂谈 #include #include #inc ...

  7. php中iconv函数使用_字符集转换编码

    php中iconv函数介绍 iconv函数库能够完成各种字符集间的转换,是php编程中不可缺少的基础函数库. 1.下载libiconv函数库http://ftp.gnu.org/pub/gnu/lib ...

  8. linux中probe函数传递参数的寻找(下)

    点击打开链接 linux中probe函数传递参数的寻找(下) 通过追寻driver的脚步,我们有了努力的方向:只有找到spi_bus_type的填充device即可,下面该从device去打通,当两个 ...

  9. Linux中pthread_create函数的实现

    转:http://blog.sina.com.cn/s/blog_6abf2c040101fpca.html 原文地址:[原]Linux中pthread_create函数的实现作者:jiq408694 ...

最新文章

  1. Laravel7使用Auth进行用户认证
  2. python读写文件绝对路径_[Spark][Python]对HDFS 上的文件,采用绝对路径,来读取获得 RDD...
  3. Post Content_Length exceeds the limit
  4. [YTU]_1096( 字符逆序)
  5. Smart Form不弹出假脱机设置界面直接打印预览
  6. 7.2 极大似然估计
  7. 【动态规划】公共子串
  8. 使用Eclipse+PyDev创建Django项目一windows下
  9. php 数组转json乱码,php将数组转为json涌现中文乱码怎么办_后端开发
  10. python自动化办公excel-Python自动化办公系列之Python操作Excel
  11. vue多语言插件vue-i18n
  12. masm32环境配置
  13. 【百度AI图像识别】LOGO帝来袭~ 个体再小、LOGO不能少
  14. matlab 仿真光学实验报告,光学信息处理实验的Matlab仿真.doc
  15. P2882 [USACO07MAR]Face The Right Way G 【贪心 + 差分】
  16. WPF窗体禁用Alt + F4键关闭窗体
  17. pdf线条粗细设置_pdf线条很模糊怎么办 如何调整pdf线条粗细
  18. TREC之使用terrier进行信息检索
  19. 如何在Qt中使用zlib
  20. 冬季送暖!实用围巾打法!(图)

热门文章

  1. c# 低功耗蓝牙_c# - 如何使用C#手动绑定到WinForm中的蓝牙低能耗设备? - 堆栈内存溢出...
  2. 怎么下载完整的python_怎么下载python并安装
  3. python整数预测_时间序列预测全攻略(附带Python代码) | 36大数据
  4. Win7旗舰版系统开启硬盘ahci模式的方法
  5. 如何打开Cookies网页
  6. Servlet第一篇【介绍Servlet、HTTP协议、WEB目录结构、编写入门Servlet程序、Servlet生命周期】
  7. java xml 读取库_Java开发中读取XML与properties配置文件的方法
  8. java 类 加载 初始化_java中类的初始化和加载
  9. windows配置samba客户端_怎样设置Samba文件服务器以使用Windows客户端
  10. c语言爱心代码空心,c语言心形图案代码,是什么?