在实际工作中,网络传输报文内容字符编码约定为UTF-8编码,linux系统接收之后,要转换为GB18030才能正常使用接收到的报文内容,这里我们利用c语言来进行字符编码的转换。
首先,我们说下要用到的函数(linux下man命令得到函数说明):
-
iconv_open:
#include <iconv.h>
The iconv_open subroutine initializes a code set converter. The code set converter is used by the iconv subroutine to convert characters from one code set to another.(iconv_open函数初始化一个字符转换标识,这个标识被iconv函数使用把字符从一种编码转换为另一种编码)
iconv_t iconv_open ( ToCode, FromCode)
const char *ToCode, *FromCode;
-
iconv:
size_t iconv (CD, InBuf, InBytesLeft, OutBuf, OutBytesLeft)
The iconv subroutine converts the string specified by the InBuf parameter into a different code set and returns the results in the OutBuf parameter.(iconv函数把InBuf参数指向的字符串转换成不同字符编码,结果保存在OutBuf参数中)
iconv_t CD;
char **OutBuf, **InBuf;
size_t *OutBytesLeft, *InBytesLeft; -
iconv_close:
int iconv_close ( CD)
The iconv_close subroutine closes a specified code set converter and deallocates any resources used by the converter.(iconv_close函数关闭指定的编码转换标识符并释放相关资源)
iconv_t CD;
然后我们开始编码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>
/*********************************************************************
*把来源字符串input从FromCode编码转换为以ToCode编码的目标字符串output
*FromCode:来源字符串编码
*ToCode :目标字符串编码
*input :来源字符串
*iLen :来源字符串长度
*output :目标字符串
*oLen :目标字符串长度
**********************************************************************/
int myEncodeConver(char *FromCode, char *ToCode, char *input, size_t *iLen, char *output, size_t *oLen)
{
char **InBuf = &input;
char **OutBuf = &output;
iconv_t CD;
CD = iconv_open(ToCode, FromCode);
if(CD == (iconv_t)-1)
{
printf("call iconv_open failed![%d][%s]\n", CD, strerror(errno));
return -5;
}
if(iconv (CD, InBuf, iLen, OutBuf, oLen))
{
printf("Call iconv failed![%d][%s]\n",errno, strerror(errno));
iconv_close(CD);
return -10;
}
iconv_close(CD);
return 0;
}
int main(int argc, char *argv[])
{
char input[100]; //存储要转码的内容
size_t iLen = 100; //长度
size_t oLen = 100; //长度
char * output = NULL; //存储转码后的内容
int ret = 0;
FILE * fp = NULL;
char *filename = "inputFile.txt";
memset(input, 0x00, sizeof(input));
/*从文件inputFile.txt中读取要转码的内容*/
fp = fopen(filename, "r");
if(fp == NULL)
{
printf("open file[%s] error!\n", filename);
return -5;
}
if( fgets(input, 100, fp))
{
output = calloc(100, sizeof(char));
ret = myEncodeConver("UTF-8", "GB18030", input, &iLen, output, &iLen);
if(ret)
{
printf("转码错误!\n");
free(output);
output = NULL;
fclose(fp);
fp = NULL;
return -10;
}
printf("input[%s]\n", input);
printf("output[%s]\n", output);
free(output);
output = NULL;
}
fclose(fp);
fp = NULL;
return 0;
}
编码完成,简单的写个makefile对程序编译:
test : test1.c然后在windows下用记事本创建文件inputFile.txt,文件内容为:“大家好,我是追风的沙儿!Nice to meet you!88!”,文件保存为UTF-8编码,然后ftp到linux系统程序相同目录下(也可以在linux系统直接生成文件,用系统的iconv命令进行转码,具体大家可以用man iconv命令查看用法)。
gcc -o test test1.c -liconv
.PHONY : clean
clean:
rm -f *.o
最后执行./test命令运行程序,结果如下:
PS:
遇到的问题,刚开始直接在程序中给input变量赋值一个utf-8的字符串,但是程序报错:
Call iconv failed![116][Invalid wide character]
转码错误!
估计是input字符串在程序中并不是真正的utf-8编码,所以最后我选择从一个utf-8编码的文件读取字符串进行转换。