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