请教iconv用法函数的用法

8307人阅读
经验总结(73)
大家都知道 iconv() 是编码转换函数,但是各个参数的具体含义可能不是那么清楚。
我简单介绍一下:
#include &iconv.h&
函数声明:
size_t iconv(iconv_t cd, char **restrict inbuf,
size_t *restrict inbytesleft, char **restrict outbuf,
size_t *restrict outbytesleft);
各参数含义:
inconv_t cd:函数iconv_open()分配的编码转换句柄。
char **restrict inbuf:指向需要编码转换的缓冲区。(其中关键字restrict只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。)
size_t *restrict inbytesleft:inbuf中还需要编码转换的字节数。
char **restrict outbuf:指向存放转码的缓冲区。
size_t *restrict outbytesleft:outbuf中还可以存放转码的字节数,也就是outbuf中的剩余空间。
博主所有文章已转自私人博客&,谢谢关注!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:424404次
积分:3906
积分:3906
排名:第6920名
原创:49篇
转载:31篇
评论:60条
(1)(1)(2)(1)(2)(1)(1)(2)(4)(1)(2)(1)(4)(6)(9)(5)(4)(10)(3)(2)(2)(7)(1)(1)(2)(1)(6)(2)php中iconv函数使用方法_PHP技巧_动态网站制作指南
php中iconv函数使用方法
来源:人气:235
中iconv函数使用方法iconv函数库能够完成各种字符集间的转换,是php编程中不可缺少的基础函数库。1、下载libiconv函数库http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.9.2.tar.gz;2、解压缩tar-zxvflibiconv-1.9.2.tar.3、安装libiconv#configure--efix=/usr/local/iconv#make#makeinstall4、重新编译php增加编译参数--with-iconv=/usr/local/iconvwindows下最近在做一个小偷程序,需要用到iconv函数把抓取来过的utf-8编码的页面转成gb2312, 发现只有用iconv函数把抓取过来的数据一转码数据就会无缘无故的少一些。 让我郁闷了好一会儿,去网上一查资料才知道这是iconv函数的一个bug。iconv在转换字符"&"到gb2312时会出错解决方法很简单,就是在需要转成的编码后加"//IGNORE"也就是iconv函数第二个参数后.如下:以下为引用的内容:复制代码代码如下:iconv("UTF-8","GB2312//IGNORE",$data)ignore的意思是忽略转换时的错误,如果没有ignore参数,所有该字符后面的字符串都无法被保存。复制代码代码如下:&?phpecho $str= '你好,这里是卖咖啡!';echo '&br /&';echo iconv('GB2312', 'UTF-8', $str); //将字符串的编码从GB2312转到UTF-8echo '&br /&';echo iconv_substr($str, 1, 1, 'UTF-8'); //按字符个数截取而非字节print_r(iconv_get_encoding()); //得到当前页面编码信息echo iconv_strlen($str, 'UTF-8'); //得到设定编码的字符串长度//也有这样用的$content = iconv("UTF-8","gbk//TRANSLIT",$content);?&iconv不是php的默认函数,也是默认安装的模块。需要安装才能用的。如果是windows2000+php,你可以修改php.ini文件,将extension=php_iconv.dll前的";"去掉,同时你要copy你的原php安装文件下的iconv.dll到你的winnt/system32下(如果你的dll指向的是这个目录)在环境下,用静态安装的方式,在configure时加多一项 --with-iconv就可以了,phpinfo看得到iconv的项。(Linux7.3+Apache4.06+php4.3.2),下载:ftp://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.8.tar.gz安装:#cp libiconv-1.8.tar.gz /usr/local/src#tar zxvf lib*#./configure --prefix=/usr/local/libiconv#make#make install编译php#./configure --prefix=/usr/local/php4.3.2 --with-iconv=/usr/local/libiconv/使用的简单例子:&?phpecho iconv("gb2312","ISO-8859-1","我们");?&PHP中的mb_convert_encoding与iconv函数介绍mb_convert_encoding这个函数是用来转换编码的。原来一直对程序编码这一概念不理解,不过现在好像有点开窍了。不过英文一般不会存在编码问题,只有中文数据才会有这个问题。比如你用Zend Studio或Editplus写程序时,用的是gbk编码,如果数据需要入,而数据库的编码为utf8时,这时就要把数据进行编码转换,不然进到数据库就会变成乱码。mb_convert_encoding的用法见官方:http://cn.php.net/manual/zh/function.mb-convert-encoding.php做一个GBK To UTF-8& ?phpheader("content-Type: text/ charset=Utf-8");echo mb_convert_encoding("妳係我的友仔", "UTF-8", "GBK");?&再来个GB2312 To Big5& ?phpheader("content-Type: text/ charset=big5");echo mb_convert_encoding("你是我的朋友", "big5", "GB2312");?&不过要使用上面的函数需要安装但是需要先enable mbstring 扩展库。PHP中的另外一个函数iconv也是用来转换字符串编码的,与上函数功能相似。下面还有一些详细的例子:iconv & Convert string to requested character encoding(PHP 4 &= 4.0.5, PHP 5)mb_convert_encoding & Convert character encoding(PHP 4 &= 4.0.6, PHP 5)用法:string mb_convert_encoding ( string str, string to_encoding [, mixed from_encoding] )需要先enable mbstring 扩展库,在 php.ini里将; extension=php_mbstring.dll 前面的 ; 去掉mb_convert_encoding 可以指定多种输入编码,它会根据内容自动识别,但是执行效率比iconv差太多;string iconv ( string in_charset, string out_charset, string str )注意:第二个参数,除了可以指定要转化到的编码以外,还可以增加两个后缀://TRANSLIT 和 //IGNORE,其中 //TRANSLIT 会自动将不能直接转化的字符变成一个或多个近似的字符,//IGNORE 会忽略掉不能转化的字符,而默认效果是从第一个非法字符截断。Returns the converted string or FALSE on failure.使用:发现iconv在转换字符&&&到gb2312时会出错,如果没有ignore参数,所有该字符后面的字符串都无法被保存。不管怎么样,这个&&&都无法转换成功,无法输出。 另外mb_convert_encoding没有这个bug.一般情况下用 iconv,只有当遇到无法确定原编码是何种编码,或者iconv转化后无法正常显示时才用mb_convert_encoding 函数.from_encoding is specified by character code name before conversion. it can be array or string - comma separated enumerated list. If it is not specified, the internal encoding will be used./* Auto detect encoding from JIS, eucjp-win, sjis-win, then convert str to UCS-2LE */$str = mb_convert_encoding($str, &UCS-2LE&, &JIS, eucjp-win, sjis-win&);/* &auto& is expanded to &ASCII,JIS,UTF-8,EUC-JP,SJIS& */$str = mb_convert_encoding($str, &EUC-JP&, &auto&);例子:$content = iconv(&GBK&, &UTF-8&P, $content);$content = mb_convert_encoding($content, "UTF-8&P,"GBK");php中使用iconv函数时容易忽略的参数今天在处理抓取内容的时候,当采用iconv进行编码转换的时候,发现结果会中断,猜是字符集的问题,考虑怎么跳过目标字符集不存在的字符,查手册发现iconv的函数只有三个参数,好像不行,然后查网上有人说可以,但是很奇怪怎么实现,最后发现英文描述有说可以加标识到目标编码后面:&TRANSLIT&,很郁闷怎么加呢?原来是先加&//&,真是郁闷,竟然有这样的设计原型: $txtContent = iconv("utf-8",'GBK',$txtContent);特殊参数:iconv("UTF-8","GB2312//IGNORE",$data)两个可选的辅助参数:TRANSLIT和IGNORE ,(其中IGNORE 就是说遇到无法转换的就跳过)。 Descrtionstring iconv ( string in_charset, string out_charset, string str )Performs a character set conversion on the string str from in_charset to out_charset. Returns the converted string or FALSE on failure.If you append the string //TRANSLIT to out_charset transliteration is activated. This means that when a character can't be represented in the target charset, it can be approximated through one or several similarly looking characters. If you append the string //IGNORE, characters that cannot be represented in the target charset are silently discarded. Otherwise, str is cut from the first illegal character.
优质网站模板&1&//&对系统iconv进行包装的函数&2&int&scsIconv(string&&strSou,&string&&strDest)&3&{&4&&&&&//&初始化转换函数&5&&&&&iconv_t&hIconv&=&&6&&&&&&&&&iconv_open(g_strDestCharSet.c_str(),&g_strSouCharSet.c_str());&7&&&&&if&(hIconv&==&(iconv_t)-1)&8&&&&&{&9&&&&&&&&&return&-1;10&&&&&}11&&&&&12&&&&&//&获取源数据13&&&&&size_t&nSouSize&=&strSou.size();14&&&&&char&*pcInBuf&=&(char*)malloc(strSou.size()&+&1);15&&&&&memset(pcInBuf,&0,&strSou.size()&+&1);16&&&&&memcpy(pcInBuf,&strSou.c_str(),&strSou.size());17&&&&&char&*pcIn&=&pcInB18&&&&&19&&&&&//&开辟目的存储空间20&&&&&size_t&nDestSize&=&TRANS_OUT_BUF_DEF_SIZE&&&2&*&nSouSize&?&21&&&&&TRANS_OUT_BUF_DEF_SIZE&:&2&*&nSouS22&&&&&char&*pcOutBuf&=&(char*)malloc(nDestSize);23&&&&&if&(!pcOutBuf)24&&&&&{25&&&&&&&&&free(pcInBuf);26&&&&&&&&&return&-1;27&&&&&}28&&&&&char&*pcOut&=&pcOutB29&&&&&30&&&&&//&开始转换31&&&&&size_t&nR32&&&&&do33&&&&&{34&&&&&&&&&memset(pcOutBuf,&0,&nDestSize);35&&&&&&&&&nRet&=&iconv(hIconv,&&pcIn,&&nSouSize,&&pcOut,&&nDestSize);36&&&&&&&&&if&(nRet&==&(size_t)-1)37&&&&&&&&&{38&&&&&&&&&&&&&if&(errno&==&E2BIG)39&&&&&&&&&&&&&{40&&&&&&&&&&&&&&&&&pcOutBuf&=&(char*)realloc(pcOutBuf,&2&*&nDestSize);41&&&&&&&&&&&&&&&&&if&(!pcOutBuf)42&&&&&&&&&&&&&&&&&{43&&&&&&&&&&&&&&&&&&&&&free(pcInBuf);44&&&&&&&&&&&&&&&&&&&&&return&-1;45&&&&&&&&&&&&&&&&&}46&&&&&&&&&&&&&&&&&pcIn&=&pcInB47&&&&&&&&&&&&&&&&&pcOut&=&pcOutB48&&&&&&&&&&&&&&&&&49&&&&&&&&&&&&&&&&&nDestSize&=&2&*&nDestS50&&&&&&&&&&&&&}51&&&&&&&&&&&&&else52&&&&&&&&&&&&&{53&&&&&&&&&&&&&&&&&free(pcInBuf);54&&&&&&&&&&&&&&&&&return&-1;55&&&&&&&&&&&&&}56&&&&&&&&&}57&&&&&&&&&else58&&&&&&&&&{59&&&&&&&&&&&&&strDest&=&pcOutB60&&&&&&&&&&&&&break;61&&&&&&&&&}62&&&&&}while&(1);63&&&&&64&&&&&free(pcInBuf);65&&&&&free(pcOutBuf);66&&&&&return&0;67&}那个小小的问题就出在iconv对源数据地址和目的数据地址的处理上,iconv执行之后对修改源数据地址和目的数据地址,简单来说就是,在iconv中会一步一步的向后移动这两个指针的指向位置,当转换结束后,均指向各自缓冲区的结尾处,因此取数据时需要注意。应该将原来的目的地址拷贝一份,以用在转换后取数据。下面是我调试时的信息图片中用红线圈起来的值体现了上面所说的iconv对源地址和目的地址的具体修改,执行iconv后的pcIn和执行前的pcIn相差的值正好等于nSouSize的大小即源数据的字节数86。执行iconv后的pcOut和执行前的pcOut相差值正好等于nDestSize前后的差值为90。这里的90和86是因为转换中只有4个中文字符,所以,长度增加了4。
阅读排行榜
评论排行榜使用iconv做内码转换 | Tony Bai
使用iconv做内码转换
十月 31, 2009
前不久某南方省份的客户反馈说我们的产品对某些生僻字(如&赟&)的支持的不好,终端收到后无法显示这个字。
经分析,发现类似&赟&这样的字在GB2312编码标准中并未收录,要想支持这样的生僻字的内码转换需要产品支持目前最新的中文编码标准GB18030。而我们的产品在诞生到现在就一直只支持GB2312,这就是导致这一问题的直接原因。
产品以前的代码库中的接口都是自己实现的,仅支持GB2312和UCS-2(即UNICODE16)之间的内码互转,如果要扩展就要更换码表。与其耗费力气找码表还不如挖掘一下开源世界最常用的内码转换工具呢。iconv既提供了命令行转换工具(),也提供一系列函数库接口供开发人员在代码里调用。很多知名的开源软件包(如等)都依赖iconv包。而iconv也几乎遍布所有unix和linux平台,iconv提供的转码支持也基本涵盖了世界范围内绝大多数主流字符集,其中支持的中文字符集就包括GBK, CP936, GB18030, BIG5等主流内码标准。
iconv的函数接口很简单,我迫不及待的想写一个例子测试一下了(不料,就在写下的这个简单的例子里我犯下了一个低级错误^_^)。
下面例子代码目的是将&赟&从UTF-8编码转换为GB18030编码(环境:GCC 3.4.6 on
for X86)。
int main() {
&&&&&&& char&&& in[8];
&&&&&&& char&&& out[255];
&&&&&&& memset(in, 0, sizeof(in));
&&&&&&& memset(out, 0, sizeof(out));
&&&&&&& in[0]&& = 0xe8; /* &赟&的UTF-8编码: E8B59F */
&&&&&&& in[1]&& = 0xb5;
&&&&&&& in[2]&& = 0x9f;
&&&&&&& size_t& inlen = strlen(in);
&&&&&&& size_t& outlen = sizeof(out);
&&&&&&& iconv_
&&&&&&& cd = iconv_open(&gb18030&,&utf-8&); /* from utf-8-&gb18030 */
&&&&&&& if (cd & 0) {
&&&&&&&&&&&&&&& printf(&iconv_open failed!\n&);
&&&&&&&&&&&&&&& return -1;
&&&&&&& if (iconv(cd, &in, &inlen, &out, &outlen) & 0) {
&&&&&&&&&&&&&&& printf(&iconv failed!\n&);
&&& &&&&&&&&&&& iconv_close(cd);
&&& &&&&&&&&&&& return -1;
&&& printf(&out = %s\n&, out);
&&& iconv_close(cd);
&&& return 0;
以上代码通过iconv_open获取一个转换描述符,这个描述符包含了转换信息(如从UTF-8转换到GB18030),然后调用iconv接口对传入的字符串进行转换,转换后的结果存储在OUT缓冲区中。
编译执行执行上面代码:
gcc -g testiconv.c -liconv
testiconv.c: In function `main':
testiconv.c:26: warning: passing arg 2 of `libiconv' from incompatible pointer type
testiconv.c:26: warning: passing arg 4 of `libiconv' from incompatible pointer type
段错误 (core dumped)
为什么会dump core呢?回顾一下编译时的Warning信息,再对比一下iconv接口的原型:
size_t iconv (iconv_t cd, const char* * inbuf, size_t * inbytesleft,
&&&&&&&&&&&&& char* * outbuf, size_t * outbytesleft);
似乎没什么问题,但又仔细分析了一下Core的栈上信息,发现了一个低级失误:
问题就出在iconv的第二个和第四个参数上,我在栈上分配了数据in和out,并简单的将&in和&out作为参数传给了iconv。iconv要得是char **类型的参数。看起来&in和&out类型也是char **,但实则不然,这也是C语言的一个陷阱。以in为例,in本身就是栈上那个数组的首地址,&in的含义与in相同,同样是数组的首地址,所以&in = in,也就是说实际上传给iconv的是一个char*而不是char**,iconv在内部对一个char*执行*操作,并以为这是一个地址,显然会导致内存错误。
修改一下代码:
&&& char&&& *p_in&&& =
&&& char&&& *p_out&&& =
&&& if (iconv(cd, &p_in, &inlen, &p_out, &outlen) & 0) {
&&&&&&&&&&&&&&& printf(&iconv failed!\n&);
&&& &&&&&&&&&&& iconv_close(cd);
&&& &&&&&&&&&&& return -1;
p_in变量在栈上分配,其本身的地址是&p_in,其值指向in这个数组的首地址,这样将&p_in传给iconv就万无一失了。
再编译执行,我们就得到了正确结果:
unix上有很多iconv实现,由于版本不同可能支持的字符集范围不同,所以为了保证代码行为一致,你可下载最新iconv包,并生成静态库(./configure –enable-static=yes),并让你的代码链接静态库。
午饭时从电视中得知:中国航天之父钱学森今天上午在北京离世。钱老可谓是中国科学家的楷模,对钱老的离世感到甚为惋惜。这里也道一句:&钱老,一路走好!&
& 2009, . 版权所有.
Related posts:
添加新评论
这里是的个人Blog,欢迎访问、订阅和留言!订阅Feed请点击上面图片。
如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!
如果您喜欢通过微信App浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
著名主机提供商Linode 10$优惠码:linode10,在即可免费获得。
阿里云推荐码:1WFZ0V,立享9折!

我要回帖

更多关于 c iconv函数 的文章

 

随机推荐