linux下c语言利用iconv函数实现utf-8转unicode
? ? 由于項(xiàng)目中需要轉(zhuǎn)換原生unicode到ascii的功能,本來(lái)想的用的是linux或者windows自帶的寬字節(jié)轉(zhuǎn)成窄字節(jié)的函數(shù),但由于本身使用了apr_iconv庫(kù),所以直接使用庫(kù)函數(shù)來(lái)解決。
? ? 期間碰到了庫(kù)函數(shù)使用一直出錯(cuò)的問(wèn)題,一個(gè)是對(duì)應(yīng)name的字符集庫(kù)文件,需要設(shè)置一下APR_ICONV1_PATH,參考鏈接:
https://www.cnblogs.com/chaohi/archive/2011/07/04/2097237.html
? ? 還有就是打印不出來(lái)outbuf中的東西。
然后參考鏈接:https://www.cnblogs.com/etangyushan/p/3753847.html找到了問(wèn)題所在(下文中的紅色部分)。
這里記錄一下:
iconv是linux下的編碼轉(zhuǎn)換的工具,它提供命令行的使用和函數(shù)接口支持
man手冊(cè)iconv命令用法如下:
iconv -f encoding -t encoding inputfile有如下選項(xiàng)可用:
輸入/輸出格式規(guī)范:
-f, --from-code=名稱 原始文本編碼 -t, --to-code=名稱 輸出編碼信息:
-l, --list 列舉所有已知的字符集輸出控制:
-c 從輸出中忽略無(wú)效的字符 -o, --output=FILE 輸出文件 -s, --silent 關(guān)閉警告 --verbose 打印進(jìn)度信息示例:下面的命令是將一個(gè)utf8編碼的文件轉(zhuǎn)換為一個(gè)unicode編碼的文件
iconv -f utf-8 -t unicode utf8file.txt> unicodefile.txticonv函數(shù)族的頭文件是iconv.h,使用前需包含之。
#include <iconv.h>iconv函數(shù)族有三個(gè)函數(shù),原型如下:
iconv_t iconv_open(const char *tocode, const char *fromcode);此函數(shù)說(shuō)明將要進(jìn)行哪兩種編碼的轉(zhuǎn)換,tocode是目標(biāo)編碼,fromcode是原編碼,該函數(shù)返回一個(gè)轉(zhuǎn)換句柄,供以下兩個(gè)函數(shù)使用。
size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);? ? ? 此函數(shù)從inbuf中讀取字符,轉(zhuǎn)換后輸出到outbuf中,inbytesleft用以記錄還未轉(zhuǎn)換的字符數(shù),outbytesleft用以記錄輸出緩沖的剩余空間。
注意: inbuf和outbuf都必須是有存儲(chǔ)空間的不能定義為常量,如: char *inbuf = "abc" 或者是char *outbuf = "123" 這樣定義都是錯(cuò)誤的。另外inbuf,inbytesleft,outbuf,outbytesleft這幾個(gè)參數(shù)在使用過(guò)程中都會(huì)改變,最好是先保存一個(gè)原值,然后再使用。
int iconv_close(iconv_t cd);
此函數(shù)用于關(guān)閉轉(zhuǎn)換句柄,釋放資源。
基本使用舉例:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iconv.h>int main(int argc, char **argv) {/* 目的編碼, TRANSLIT:遇到無(wú)法轉(zhuǎn)換的字符就找相近字符替換* IGNORE :遇到無(wú)法轉(zhuǎn)換字符跳過(guò)*///char *encTo = "UNICODE//TRANSLIT";char *encTo = "UNICODE//IGNORE";/* 源編碼 */char *encFrom = "UTF-8";/* 獲得轉(zhuǎn)換句柄*@param encTo 目標(biāo)編碼方式*@param encFrom 源編碼方式** */iconv_t cd = iconv_open (encTo, encFrom);if (cd == (iconv_t)-1){perror ("iconv_open");}/* 需要轉(zhuǎn)換的字符串 */char inbuf[1024] = "abcdef哈哈哈哈行"; size_t srclen = strlen (inbuf);/* 打印需要轉(zhuǎn)換的字符串的長(zhǎng)度 */printf("srclen=%d\n", srclen);/* 存放轉(zhuǎn)換后的字符串 */size_t outlen = 1024;char outbuf[outlen];memset (outbuf, 0, outlen);/* 由于iconv()函數(shù)會(huì)修改指針,所以要保存源指針 */char *srcstart = inbuf;char *tempoutbuf = outbuf;/* 進(jìn)行轉(zhuǎn)換*@param cd iconv_open()產(chǎn)生的句柄*@param srcstart 需要轉(zhuǎn)換的字符串*@param srclen 存放還有多少字符沒(méi)有轉(zhuǎn)換*@param tempoutbuf 存放轉(zhuǎn)換后的字符串*@param outlen 存放轉(zhuǎn)換后,tempoutbuf剩余的空間** */size_t ret = iconv (cd, &srcstart, &srclen, &tempoutbuf, &outlen);if (ret == -1){perror ("iconv");}printf ("inbuf=%s, srclen=%d, outbuf=%s, outlen=%d\n", inbuf, srclen, outbuf, outlen);int i = 0;for (i=0; i<strlen(outbuf); i++){printf("%x\n", outbuf[i]);} /* 關(guān)閉句柄 */iconv_close (cd);return 0; }下面做了一下函數(shù)的封裝:
/** =====================================================================================** Filename: iconv.c** Description: j** Version: 1.0* Created: 08/05/2015 05:51:47 PM* Revision: none* Compiler: gcc** Author: YOUR NAME (), * Organization: ** =====================================================================================*/#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <iconv.h> bool unicode_to_utf8 (char *inbuf, size_t *inlen, char *outbuf, size_t *outlen) {/* 目的編碼, TRANSLIT:遇到無(wú)法轉(zhuǎn)換的字符就找相近字符替換* IGNORE :遇到無(wú)法轉(zhuǎn)換字符跳過(guò)*/char *encTo = "UTF-8//IGNORE"; /* 源編碼 */char *encFrom = "UNICODE";/* 獲得轉(zhuǎn)換句柄*@param encTo 目標(biāo)編碼方式*@param encFrom 源編碼方式** */iconv_t cd = iconv_open (encTo, encFrom);if (cd == (iconv_t)-1){perror ("iconv_open");}/* 需要轉(zhuǎn)換的字符串 */printf("inbuf=%s\n", inbuf);/* 打印需要轉(zhuǎn)換的字符串的長(zhǎng)度 */printf("inlen=%d\n", *inlen);/* 由于iconv()函數(shù)會(huì)修改指針,所以要保存源指針 */char *tmpin = inbuf;char *tmpout = outbuf;size_t insize = *inlen;size_t outsize = *outlen;/* 進(jìn)行轉(zhuǎn)換*@param cd iconv_open()產(chǎn)生的句柄*@param srcstart 需要轉(zhuǎn)換的字符串*@param inlen 存放還有多少字符沒(méi)有轉(zhuǎn)換*@param tempoutbuf 存放轉(zhuǎn)換后的字符串*@param outlen 存放轉(zhuǎn)換后,tempoutbuf剩余的空間** */size_t ret = iconv (cd, &tmpin, inlen, &tmpout, outlen);if (ret == -1){perror ("iconv");}/* 存放轉(zhuǎn)換后的字符串 */printf("outbuf=%s\n", outbuf);//存放轉(zhuǎn)換后outbuf剩余的空間printf("outlen=%d\n", *outlen);int i = 0;for (i=0; i<(outsize- (*outlen)); i++){//printf("%2c", outbuf[i]);printf("%x\n", outbuf[i]);}/* 關(guān)閉句柄 */iconv_close (cd);return 0; }bool utf8_to_unicode (char *inbuf, size_t *inlen, char *outbuf, size_t *outlen) {/* 目的編碼, TRANSLIT:遇到無(wú)法轉(zhuǎn)換的字符就找相近字符替換* IGNORE :遇到無(wú)法轉(zhuǎn)換字符跳過(guò)*/char *encTo = "UNICODE//IGNORE";/* 源編碼 */char *encFrom = "UTF-8";/* 獲得轉(zhuǎn)換句柄*@param encTo 目標(biāo)編碼方式*@param encFrom 源編碼方式** */iconv_t cd = iconv_open (encTo, encFrom);if (cd == (iconv_t)-1){perror ("iconv_open");}/* 需要轉(zhuǎn)換的字符串 */printf("inbuf=%s\n", inbuf);/* 打印需要轉(zhuǎn)換的字符串的長(zhǎng)度 */printf("inlen=%d\n", *inlen);/* 由于iconv()函數(shù)會(huì)修改指針,所以要保存源指針 */char *tmpin = inbuf;char *tmpout = outbuf;size_t insize = *inlen;size_t outsize = *outlen;/* 進(jìn)行轉(zhuǎn)換*@param cd iconv_open()產(chǎn)生的句柄*@param srcstart 需要轉(zhuǎn)換的字符串*@param inlen 存放還有多少字符沒(méi)有轉(zhuǎn)換*@param tempoutbuf 存放轉(zhuǎn)換后的字符串*@param outlen 存放轉(zhuǎn)換后,tempoutbuf剩余的空間** */size_t ret = iconv (cd, &tmpin, inlen, &tmpout, outlen);if (ret == -1){perror ("iconv");}/* 存放轉(zhuǎn)換后的字符串 */printf("outbuf=%s\n", outbuf);//存放轉(zhuǎn)換后outbuf剩余的空間printf("outlen=%d\n", *outlen);int i = 0;for (i=0; i<(outsize- (*outlen)); i++){//printf("%2c", outbuf[i]);printf("%x\n", outbuf[i]);}/* 關(guān)閉句柄 */iconv_close (cd);return 0; }int main () {/* 需要轉(zhuǎn)換的字符串 *///char inbuf[1024] = "abcdef哈哈哈哈行"; char *text = "漢"; char inbuf[1024] = {};strcpy (inbuf, text);size_t inlen = strlen (inbuf);/* 存放轉(zhuǎn)換后的字符串 */char outbuf[1024] = {};size_t outlen = 1024;utf8_to_unicode (inbuf, &inlen, outbuf, &outlen);printf ("print outbuf: %s\n", outbuf);size_t outsize = strlen(outbuf);size_t insize = 1024;char instr[1024] = {};unicode_to_utf8 (outbuf, &outsize, instr, &insize);printf ("print buf: %s\n", instr);return 0; }?
總結(jié)
以上是生活随笔為你收集整理的linux下c语言利用iconv函数实现utf-8转unicode的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 将fork出来的分支与原项目合并
- 下一篇: #,#x,\u开头的unicode介绍