為博羅等地區(qū)用戶(hù)提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及博羅網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站制作、成都網(wǎng)站建設(shè)、博羅網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶(hù)提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶(hù)的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
場(chǎng)景說(shuō)明
將UTF-8的編碼轉(zhuǎn)換成GBK編碼,使用Notepad++創(chuàng)建一個(gè)UTF-8(無(wú)BOM)的編碼文件,文件內(nèi)容簡(jiǎn)單為風(fēng)雨在途,保存文件名稱(chēng)為utf8.txt,轉(zhuǎn)換之后存儲(chǔ)文件名稱(chēng)為gbk.txt.
iconv -f UTF8 -t GBK
#include
size_t iconv(iconv_t cd,
char **inbuf, size_t*inbytesleft,
char **outbuf, size_t*outbytesleft);
參數(shù)說(shuō)明:經(jīng)過(guò)iconv函數(shù)之后,*outbuf當(dāng)前指向轉(zhuǎn)換之后的字符串的最后位置,*inuf當(dāng)前指向被轉(zhuǎn)換字符串的最后位置,所以為了得到正確的轉(zhuǎn)換字符串的指針位置,需要進(jìn)行如下的調(diào)整:
*outbuf = *outbuf - iconv函數(shù)的返回值.或者定義指針指向當(dāng)前的字符串緩存區(qū),就不會(huì)修改字符串的緩沖區(qū)指針了
int UTF8fileToGBKfile()
{
int ret;
int read_fd;
int write_fd;
//1打開(kāi)文件,讀取utf-8文件
read_fd=open("utf8.txt",O_RDONLY|O_CREAT);
write_fd=open("gbk.txt", O_WRONLY|O_CREAT);
char utfBuffer[256] = {0};
size_t inLen = read(read_fd, utfBuffer,256);
//2獲取字符集轉(zhuǎn)換的文件句柄,這里是從utf-8轉(zhuǎn)換為gbk
errno = 0;
iconv_t cd = iconv_open("gbk","utf-8");
char* errMsg = NULL;
if (errno !=0)
{
errMsg = strerror(errno);
cout< cout< return -1; } //3準(zhǔn)備轉(zhuǎn)換前的字符串,避免修改原字符串 char* szSrc = (char*)malloc(inLen); memset(szSrc, 0, inLen); memcpy(szSrc, utfBuffer, inLen); //4準(zhǔn)備轉(zhuǎn)換后的字符串存儲(chǔ)空間 size_t outLen = 256; char* szDest = (char*)malloc(outLen); memset(szDest, 0, outLen); //4開(kāi)始轉(zhuǎn)換 errno = 0; char* pszDest = szDest; char* pszSrc = szDest; errno = 0; ret = iconv(cd, &pszSrc, &inLen,&pszDest , &outLen); if (errno !=0) { errMsg = strerror(errno); cout< cout< return -2; } iconv_close(cd); //5寫(xiě)入文件,outlen是剩下多少空間沒(méi)有使用 ret = write(write_fd, szDest, 256-outLen); close(read_fd); close(write_fd); free(szDest); free(szSrc); return 0; } 下載libiconv-1.14.tar.gz,解壓,執(zhí)行./configure --prefix=/opt/iconv;make;make install 生成文件: charset.alias libcharset.so libiconv.la libiconv.so.2.5.1 libcharset.a libcharset.so.1 libiconv.so preloadable_libiconv.so libcharset.la libcharset.so.1.0.0 libiconv.so.2 實(shí)際鏈接到庫(kù)的時(shí)候,指定庫(kù)目錄,在/etc/ld.so.conf文件之后追加一行/opt/iconv/lib.采用ldconfig命令的時(shí)候,出錯(cuò): libcharset.so.1 不是符號(hào)鏈接 libiconv.so.2 不是符號(hào)鏈接 原因是:刪除這兩個(gè)文件,然后使用ldconfig命令,生成該符號(hào)鏈接。 [root@jack lib]# ll 總用量 3560 -rw-r--r--. 1 root root 212 9月 13 10:22 charset.alias -rw-r--r--. 1 root root 27868 9月 13 10:22 libcharset.a -rw-r--r--. 1 root root 936 9月 13 10:22 libcharset.la -rw-r--r--. 1 root root 277609月 13 10:22 libcharset.so lrwxrwxrwx. 1 root root 19 9月 13 11:10libcharset.so.1->libcharset.so.1.0.0 -rw-r--r--. 1 root root 27760 9月 13 10:22 libcharset.so.1.0.0 -rw-r--r--. 1 root root 912 9月 13 10:22 libiconv.la -rw-r--r--. 1 root root 1186436 9月 13 10:22 libiconv.so lrwxrwxrwx. 1 root root 17 9月 13 11:10 libiconv.so.2 ->libiconv.so.2.5.1 -rw-r--r--. 1 root root 1186436 9月 13 10:22 libiconv.so.2.5.1 -rw-r--r--. 1 root root 1168119 9月 13 10:22 preloadable_libiconv.so 調(diào)用該動(dòng)態(tài)庫(kù)的編譯命令如下: g++ test.cpp -I/opt/iconv/include//opt/iconv/lib/libcharset.a/opt/iconv/lib/libiconv.so libsqlite3.a-lpthread -ldl -g -o main ./configure--prefix=/opt/iconvCFLAGS="-g -O0" 生成動(dòng)態(tài)庫(kù)鏈接符號(hào)錯(cuò)誤解決 [root@jack lib]# ldconfig ldconfig: /opt/iconv/lib/libiconv.so.2 不是符號(hào)連接 ldconfig: /opt/iconv/lib/libcharset.so.1 不是符號(hào)連接 [root@jack lib]# rm -rflibiconv.so.2libcharset.so.1 [root@jack lib]# ldconfig 主要是將UTF-8編碼的字符串在轉(zhuǎn)換成GBK編碼,詳細(xì)的轉(zhuǎn)換規(guī)則UTF-8轉(zhuǎn)Unicode, 然后Unicode編碼通過(guò)查表,映射到GBK編碼上 loop_unicode.h:273 執(zhí)行函數(shù) incount=cd->ifuncs.xxx_mbtowc(cd,&wc,inptr,inleft); 跳轉(zhuǎn)到./utf8.h:30 核心轉(zhuǎn)換函數(shù):static size_t unicode_loop_convert (iconv_t icd, const char* * inbuf, size_t *inbytesleft,char* *outbuf,size_t*outbytesleft) at./loop_unicode.h:284 284 incount = cd->ifuncs.xxx_mbtowc(cd,&wc,inptr,inleft); at./loop_unicode.h:362 362 outcount = cd->ofuncs.xxx_wctomb(cd,outptr,wc,outleft); 該函數(shù)進(jìn)行Unicode轉(zhuǎn)換成GBK 進(jìn)行的是查表進(jìn)行轉(zhuǎn)換,在調(diào)試的過(guò)程中,可以通過(guò)附件,提前知道轉(zhuǎn)換的字符編碼,然后查看iconv庫(kù)是否轉(zhuǎn)換有問(wèn)題 UTF-8轉(zhuǎn)Unicode編碼的函數(shù): static int utf8_mbtowc (conv_t conv, ucs4_t*pwc,constunsigned char *s, int n) iconv函數(shù)中傳遞進(jìn)去的outptr會(huì)指向轉(zhuǎn)換字符串的末尾,所以需要進(jìn)行指針的前移,outptr-返回值 就是指向最開(kāi)始轉(zhuǎn)換的字符串 iconv_open函數(shù)跳轉(zhuǎn)到lib/iconv.c 218 行,里面調(diào)用了 #include "iconv_open1.h" 47-60行 141-152行 for (cp = fromcode, bp = buf, count = MAX_WORD_LENGTH+10+1; ; cp++,bp++){ unsigned char c = * (unsigned char *) cp; if (c >= 0x80) goto invalid; if (c >= 'a' && c <= 'z') c -= 'a'-'A'; *bp = c; if (c == '\0') break; if (--count == 0) goto invalid; } 這里進(jìn)行了大小寫(xiě)轉(zhuǎn)換,所有的字體編碼類(lèi)型,轉(zhuǎn)換成大寫(xiě)字母,gbk轉(zhuǎn)換成GBK.小寫(xiě)字母轉(zhuǎn)換成大寫(xiě)字母是減去26 目前遇到一個(gè)相當(dāng)大的問(wèn)題: ap= aliases_lookup(buf,bp-buf); if(ap == NULL) { ap = aliases2_lookup(buf); if (ap == NULL) goto invalid; } 這幾行函數(shù)沒(méi)能夠單步調(diào)試所以并不清楚返回值進(jìn)行了什么操作 #include "iconv_open2.h" 設(shè)置執(zhí)行的回調(diào)函數(shù),以及初始化標(biāo)志位,具體的沒(méi)有看出什么 使用庫(kù)提供的automake,順利生成libiconv.so文件,目前嘗試單獨(dú)編譯,出現(xiàn)如下的問(wèn)題 使用指令如下: g++libiconv-1.14/libcharset/lib/localcharset.clibiconv-1.14/lib/iconv.clibiconv-1.14/lib/relocatable.c libsqlite3.a -lpthread -ldl -Ilibiconv-1.14/-I libiconv-1.14/include/-I libiconv-1.14/lib-Ilibiconv-1.14/libcharset/include/ -fPIC -shared -o libiconv.so libiconv-1.14/libcharset/lib/localcharset.c:77:25:錯(cuò)誤:configmake.h:沒(méi)有那個(gè)文件或目錄 libiconv-1.14/libcharset/lib/localcharset.c:Infunction‘const char* get_charset_aliases()’: libiconv-1.14/libcharset/lib/localcharset.c:135:錯(cuò)誤:‘LIBDIR’在此作用域中尚未聲明 查找資料顯示在windows下無(wú)需該文件,因此注釋該頭文件的包含 問(wèn)題剩下LIBDIR的定義問(wèn)題 查找所有的引用LIBDIR ,localcharset.c函數(shù) static const char*get_charset_aliases(void)會(huì)通過(guò)dir =relocate (LIBDIR); 獲取該值,查看該函數(shù)的內(nèi)容: const char *cp; cp=charset_aliases; /* Pointer to the contentsofthecharset.alias file, if it has already been read, else NULL. Its format is: ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0'CANONICAL_n '\0''\0' */ static const char *volatilecharset_aliases; 說(shuō)明指向這個(gè)charset.alias文件,查看該文件: 該文件的目錄如下: libiconv-1.14/libcharset/lib 內(nèi)容如下: # This file contains a table ofcharacterencodingaliases, # suitable for operating system'linux-gnu'. # It was automatically generatedfromconfig.charset. # Packages using this file: ISO_646.IRV:1983 ASCII 說(shuō)明該文件是由同一級(jí)目錄下的config.charset腳本生成的 跟蹤: linux* | *-gnu*) #With glibc-2.1 or newer, we don't need any canonicalization, #because glibc has iconv and both glibc and libiconv support all #GNU canonical names directly. Therefore, the Makefile does not #need to install the alias file at all. #The following applies only to glibc-2.0.x and older libcs. echo "ISO_646.IRV:1983 ASCII" 翻譯:glibc-2.1以后的版本都不需要任何的標(biāo)準(zhǔn)化文件,因?yàn)樽詭У木壒?,該文件只是被之前的版本引?/p> 因此在localcharset.c 定義LIBDIR指向的目錄: #defineLIBDIR"/work/libiconv-1.14/libcharset/lib" [root@jack work]# g++libiconv-1.14/libcharset/lib/localcharset.clibiconv-1.14/lib/relocatable.c libiconv-1.14/lib/iconv.c test.cpp -I libiconv-1.14/ -Ilibiconv-1.14/lib/-Ilibiconv-1.14/include -Ilibiconv-1.14/libcharset/include/ -I libiconv-1.14/srclib/ libsqlite3.a -lpthread -ldl -o testmain /tmp/cc1ENLex.o: Infunction`libiconv_open': iconv.c:(.text+0x18206):undefinedreferenceto `aliases_lookup(char const*, unsigned int)' iconv.c:(.text+0x18391):undefinedreferenceto `aliases_lookup(char const*, unsigned int)' /tmp/cc1ENLex.o:Infunction`libiconv_open_into': iconv.c:(.text+0x187d0): undefinedreferenceto`aliases_lookup(char const*, unsigned int)' iconv.c:(.text+0x1895b):undefinedreferenceto `aliases_lookup(char const*, unsigned int)' /tmp/cc1ENLex.o: Infunction`iconv_canonicalize': iconv.c:(.text+0x190a9):undefinedreferenceto `aliases_lookup(char const*, unsigned int)' collect2: ld 返回 1 該函數(shù)的定義就在lib/aliases.h文件當(dāng)中定義的,不清楚為什么無(wú)法找到, 然后手動(dòng)將該定義拷貝到lib/iconv.c文件,還是出現(xiàn)同樣子的問(wèn)題2 編譯調(diào)試
2.1禁用優(yōu)化安裝
2.2禁用優(yōu)化
2.3 GDB調(diào)試源碼
2.4手動(dòng)編寫(xiě)指令構(gòu)建動(dòng)態(tài)庫(kù)
網(wǎng)頁(yè)題目:iconv用法
網(wǎng)頁(yè)URL:http://weahome.cn/article/peissp.html