libiconv庫(kù)是一個(gè)基于GNU協(xié)議的開(kāi)源庫(kù),主要是解決多語(yǔ)言編碼處理轉(zhuǎn)換等應(yīng)用問(wèn)題。
怎樣學(xué)習(xí)使用libiconv庫(kù)?對(duì)于剛接觸到人來(lái)說(shuō),這篇文章不妨去看一看,若已經(jīng)用到過(guò)該庫(kù)的人,在應(yīng)用的過(guò)程中可能遇到一些問(wèn)題,我們可以一起來(lái)探討,我的聯(lián)系方式是 cnangel@gmail.com 。
幾個(gè)函數(shù)原型:
iconv_t iconv_open(const char *tocode, const char *fromcode);
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
int iconv_close(iconv_t cd);
其中:
iconv_open是打開(kāi)一個(gè)編碼流,類(lèi)似于打開(kāi)一個(gè)編碼管道(通道),出錯(cuò)則返回 -1;
iconv用于具體輸入的轉(zhuǎn)換,如果出錯(cuò),則返回 -1,否則返回 0;
iconv_close是關(guān)閉該管道(通道)。
舉個(gè)例子:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iconv.h>
#define OUTLEN 255
int covert(char *, char *, char *, size_t , char *, size_t );
int main(int argc, char *argv[])
{
char *input = "中國(guó)";
size_t len = strlen(input);
char *output = (char *)malloc(OUTLEN);
covert("UTF-8", "GBK", input, len, output, OUTLEN);
printf("%s\n", output);
return 0;
}
int covert(char *desc, char *src, char *input, size_t ilen, char *output, size_t olen)
{
char **pin = &input;
char **pout = &output;
iconv_t cd = iconv_open(desc, src);
if (cd == (iconv_t)-1)
{
return -1;
}
memset(output, 0, olen);
if (iconv(cd, pin, &ilen, pout, &olen)) return -1;
iconv_close(cd);
return 0;
}
這里面covert函數(shù)就是用于將編碼進(jìn)行轉(zhuǎn)換,其中要注意的地方是iconv函數(shù)的傳遞參數(shù):
1,iconv傳遞有5個(gè)參數(shù);
2,第3個(gè)參數(shù)和第5個(gè)參數(shù)一般是input和output實(shí)際分配的大小,一般是 sizeof(type)*strlen(string);
3,第4個(gè)參數(shù)是不能直接傳遞指針的地址,因?yàn)?span lang="EN-US">iconv函數(shù)能夠改變指針的值,所以需要復(fù)制一份指針變量;
如果對(duì)于大量需要轉(zhuǎn)換的編碼,上述函數(shù)covert不適合該方式,一是內(nèi)存的限制不能一次調(diào)用,二是若分多次調(diào)用會(huì)頻繁打開(kāi)一個(gè)編碼管道(通道),導(dǎo)致資源浪費(fèi),最好的辦法還是拆開(kāi)該函數(shù)根據(jù)情況使用。
這里補(bǔ)充一下代碼:
translateSP.h:
#ifndef __TRANSLATESP_H_
#define __TRANSLATESP_H_
#include <iconv.h>
class TranslateSP
{
public:
TranslateSP():i_cd(0){}
TranslateSP(const char *from_charset,const char *to_charset)
{
i_cd = iconv_open(to_charset, from_charset);
if ((iconv_t)-1 == i_cd) printf("iconv open error!\n");
}
~TranslateSP()
{
if (i_cd)
iconv_close(i_cd);
}
public:
size_t translate(char *src, size_t srcLen, char *desc, size_t descLen);
size_t convert(const char *from_charset, const char *to_charset,
char *src, size_t srcLen, char *desc, size_t descLen);
private:
iconv_t i_cd;
};
#endif
translateSP.cpp:
#include "translateSP.h"
#define MAX_LEN 200
size_t TranslateSP::translate(char *src, size_t srcLen, char *desc, size_t descLen)
{
char **inbuf = &src;
char **outbuf = &desc;
memset(desc, 0, descLen);
return iconv(i_cd, inbuf, &srcLen, outbuf, &descLen);
}
size_t TranslateSP::convert(const char *from_charset, const char *to_charset,
char *src, size_t srcLen, char *desc, size_t descLen)
{
char **inbuf = &src;
char **outbuf = &desc;
iconv_t cd = iconv_open(to_charset, from_charset);
if ((iconv_t)-1 == cd) return (size_t)-1;
memset(desc, 0, descLen);
size_t n = iconv(cd, inbuf, &srcLen, outbuf, &descLen);
iconv_close(cd);
return n;
}
int main(int argc, char *argv[])
{
char *str = "我愛(ài)zhong國(guó)! %#@#";
char *str1 = "i大量需要轉(zhuǎn)換的編碼";
char *str2 = "函數(shù)就是用于將hello進(jìn)行轉(zhuǎn)換";
char newstr[MAX_LEN];
TranslateSP tsp;
tsp.convert("utf-8", "gbk", str, strlen(str), newstr, MAX_LEN);
printf("%s\n", newstr);
TranslateSP newtsp("UTF-8", "GBK");
newtsp.translate(str1, strlen(str1), newstr, MAX_LEN);
printf("%s\n", newstr);
newtsp.translate(str2, strlen(str2), newstr, MAX_LEN);
printf("%s\n", newstr);
return 0;
}
編譯:
g++ translateSP.cpp -o test
./test
我愛(ài)zhong國(guó)! %#@#
i大量需要轉(zhuǎn)換的編碼
函數(shù)就是用于將hello進(jìn)行轉(zhuǎn)換
(以上輸出是GBK編碼)