iconv 文件編碼轉換
http://qq164587043.blog.51cto.com/261469/63349?
linux shell 配置文件中默認的字符集編碼為UTF-8 。UTF-8是unicode的一種表達方式,gb2312是和unicode都是字符的編碼方式,所以說gb2312跟utf-8的概念應該不是一個層次上的。在LINUX上進行編碼轉換時,可以利用iconv命令實現,這是針對文件的,即將指定文件從一種編碼轉換為另一種編碼。
?查了下iconv命令用法如下:
iconv [選項...] [文件...]有如下選項可用:
輸入/輸出格式規范:
-f, --from-code=名稱 原始文本編碼
-t, --to-code=名稱 輸出編碼
信息:
-l, --list 列舉所有已知的字符集
輸出控制:
-c 從輸出中忽略無效的字符
-o, --output=FILE 輸出文件
-s, --silent 關閉警告
--verbose 打印進度信息
iconv -f utf-8 -t gb2312 /server_test/reports/software_.txt > /server_test/reports/software_asserts.txt
?
?
iconv函數族的頭文件是iconv.h,使用前需包含之。#include <iconv.h>
iconv函數族有三個函數,原型如下:
(1) iconv_t iconv_open(const char *tocode, const char *fromcode);
此函數說明將要進行哪兩種編碼的轉換,tocode是目標編碼,fromcode是原編碼,該函數返回一個轉換句柄,供以下兩個函數使用。
(2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);
此函數從inbuf中讀取字符,轉換后輸出到outbuf中,inbytesleft用以記錄還未轉換的字符數,outbytesleft用以記錄輸出緩沖的剩余空間。 (3) int iconv_close(iconv_t cd);
此函數用于關閉轉換句柄,釋放資源。
例子1: 用C語言實現的轉換示例程序
/* f.c : 代碼轉換示例C程序 */
#include <iconv.h>
#define OUTLEN 255
main()
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安裝";
char out[OUTLEN];
//unicode碼轉為gb2312碼
rc = u2g(in_utf8,strlen(in_utf8),out,OUTLEN);
printf("unicode-->gb2312 out=%sn",out);
//gb2312碼轉為unicode碼
rc = g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN);
printf("gb2312-->unicode out=%sn",out);
}
//代碼轉換:從一種編碼轉為另一種編碼
int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;
cd = iconv_open(to_charset,from_charset);
if (cd==0) return -1;
memset(outbuf,0,outlen);
if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
//UNICODE碼轉為GB2312碼
int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
//GB2312碼轉為UNICODE碼
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);
}
例子2: 用C++語言實現的轉換示例程序
/* f.cpp : 代碼轉換示例C++程序 */
#include <iconv.h>
#include <iostream>
#define OUTLEN 255
using namespace std;
// 代碼轉換操作類
class CodeConverter {
private:
iconv_t cd;
public:
// 構造
CodeConverter(const char *from_charset,const char *to_charset) {
cd = iconv_open(to_charset,from_charset);
}
// 析構
~CodeConverter() {
iconv_close(cd);
}
// 轉換輸出
int convert(char *inbuf,int inlen,char *outbuf,int outlen) {
char **pin = &inbuf;
char **pout = &outbuf;
memset(outbuf,0,outlen);
return iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
}
};
int main(int argc, char **argv)
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安裝";
char out[OUTLEN];
// utf-8-->gb2312
CodeConverter cc = CodeConverter("utf-8","gb2312");
cc.convert(in_utf8,strlen(in_utf8),out,OUTLEN);
cout << "utf-8-->gb2312 in=" << in_utf8 << ",out=" << out << endl;
// gb2312-->utf-8
CodeConverter cc2 = CodeConverter("gb2312","utf-8");
cc2.convert(in_gb2312,strlen(in_gb2312),out,OUTLEN);
cout << "gb2312-->utf-8 in=" << in_gb2312 << ",out=" << out << endl;
}
?
?
?
iconv的支持的編碼有
|
?
?http://worldant.blog.sohu.com/96069463.html?
?? 在LINUX上進行編碼轉換時,既可以利用iconv函數族編程實現,也可以利用iconv命令來實現,只不過后者是針對文件的,即將指定文件從一種編碼轉換為另一種編碼。? (1) 利用iconv函數族進行編碼轉換
? iconv函數族的頭文件是iconv.h,使用前需包含之。
?????? #include <iconv.h>
? iconv函數族有三個函數,原型如下:
- 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);
?(2) 利用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文件。
2.iconv實現通用語言編碼轉換(c++)
?? 可以實現對任意的兩個iconv支持的語言編碼做互相轉換,比如GB2312, GBK, GB18030, UTF-8, UTF-16, BIG5等.
下面這段程序,非常的穩定,測試了超過10萬行的數十種編碼的文本的轉換都沒有出問題。?
#include?<stdio.h>
#include?<stdlib.h>
#include?<string.h>
#include?<iconv.h>
#ifndef?ICONV_CONST
#?define?ICONV_CONST?const
#endif
/*!
?對字符串進行語言編碼轉換
?param?from??原始編碼,比如"GB2312",的按照iconv支持的寫
?param?to??????轉換的目的編碼
?param?save??轉換后的數據保存到這個指針里,需要在外部分配內存
?param?savelen?存儲轉換后數據的內存大小
?param?src??????原始需要轉換的字符串
?param?srclen????原始字符串長度
?*/
int
convert(const?char?*from,?const?char?*to,?char*?save,?int?savelen,?char?*src,?int?srclen)
{
????iconv_t?cd;
????char???*inbuf?=?src;
????char?*outbuf?=?save;
????size_t?outbufsize?=?savelen;
????int?status?=?0;
????size_t??savesize?=?0;
????size_t?inbufsize?=?srclen;
????const?char*?inptr?=?inbuf;
????size_t??????insize?=?inbufsize;
????char*?outptr?=?outbuf;
????size_t?outsize?=?outbufsize;
????
????cd?=?iconv_open(to,?from);
????iconv(cd,NULL,NULL,NULL,NULL);
????if?(inbufsize?==?0)?{
????????status?=?-1;
????????goto?done;
????}
????while?(insize?>?0)?{
????????size_t?res?=?iconv(cd,(ICONV_CONST?char**)&inptr,&insize,&outptr,&outsize);
????????if?(outptr?!=?outbuf)?{
????????????int?saved_errno?=?errno;
????????????int?outsize?=?outptr?-?outbuf;
????????????strncpy(save+savesize,?outbuf,?outsize);
????????????errno?=?saved_errno;
????????}
????????if?(res?==?(size_t)(-1))?{
????????????if?(errno?==?EILSEQ)?{
????????????????int?one?=?1;
????????????????iconvctl(cd,ICONV_SET_DISCARD_ILSEQ,&one);
????????????????status?=?-3;
????????????}?else?if?(errno?==?EINVAL)?{
????????????????if?(inbufsize?==?0)?{
????????????????????status?=?-4;
????????????????????goto?done;
????????????????}?else?{
????????????????????break;
????????????????}
????????????}?else?if?(errno?==?E2BIG)?{
????????????????status?=?-5;
????????????????goto?done;
????????????}?else?{
????????????????status?=?-6;
????????????????goto?done;
????????????}
????????}
????}
????status?=?strlen(save);
done:
????iconv_close(cd);
????return?status;
}
附:關于iconv的能力
It provides support for the encodings:
- European languages
- ASCII, ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16}, KOI8-R, KOI8-U, KOI8-RU, CP{1250,1251,1252,1253,1254,1257}, CP{850,866}, Mac{Roman,CentralEurope,Iceland,Croatian,Romania}, Mac{Cyrillic,Ukraine,Greek,Turkish}, Macintosh Semitic languages
- ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic} Japanese
- EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1 Chinese
- EUC-CN, HZ, GBK, CP936, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, BIG5-HKSCS:2001, BIG5-HKSCS:1999, ISO-2022-CN, ISO-2022-CN-EXT Korean
- EUC-KR, CP949, ISO-2022-KR, JOHAB Armenian
- ARMSCII-8 Georgian
- Georgian-Academy, Georgian-PS Tajik
- KOI8-T Kazakh
- PT154, RK1048 Thai
- ISO-8859-11, TIS-620, CP874, MacThai Laotian
- MuleLao-1, CP1133 Vietnamese
- VISCII, TCVN, CP1258 Platform specifics
- HP-ROMAN8, NEXTSTEP Full Unicode
- UTF-8?
UCS-2, UCS-2BE, UCS-2LE?
UCS-4, UCS-4BE, UCS-4LE?
UTF-16, UTF-16BE, UTF-16LE?
UTF-32, UTF-32BE, UTF-32LE?
UTF-7?
C99, JAVA Full Unicode, in terms of? - UCS-2-INTERNAL, UCS-4-INTERNAL Locale dependent, in terms of `char' or `wchar_t' (with machine dependent endianness and alignment, and with OS and locale dependent semantics)
- char, wchar_t?
The empty encoding name "" is equivalent to "char": it denotes the locale dependent character encoding.
uint16_t
?or?uint32_t
?(with machine dependent endianness and alignment)--enable-extra-encodings
, it also provides support for a few extra encodings: - European languages
- CP{437,737,775,852,853,855,857,858,860,861,863,865,869,1125} Semitic languages
- CP864 Japanese
- EUC-JISX0213, Shift_JISX0213, ISO-2022-JP-3 Chinese
- BIG5-2003 (experimental) Turkmen
- TDS565 Platform specifics
- ATARIST, RISCOS-LATIN1
It has also some limited support for transliteration, i.e. when a character cannot be represented in the target character set, it can be approximated through one or several similarly looking characters. Transliteration is activated when "//TRANSLIT" is appended to the target encoding name.
[參考]iconv
http://www.gnu.org/software/libiconv/documentation/libiconv/iconv.1.html
http://www.gnu.org/software/libiconv/
[參考]iconv實現通用語言編碼轉換
http://www.yuanma.org/data/2008/0503/article_3025.htm
[參考]linux下字符集編碼轉換輕松實現?
http://blog.csdn.net/hnhbdss/archive/2007/11/30/1909456.aspx