中文编码之间的转换

//主要思想:先将一种编码用MultiByteToWideChar函数变为Unicode编码,再用WideCharToMultiByte函数变为另一种编码。


/*********************************
MultiByteToWideChar
一、函数功能:该函数映射一个字符串到一个unicode字符串。  
二、函数原型:int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cchMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
三、参数说明:
1.CodePage:指定执行转换的编码。常用的有CP_ACP:ANSI(gb*)、CP_UTF8:UTF-8
2.dwFlags:一组位标记用以指出是否未转换成预作或宽字符(若组合形式存在),是否使用象形文字替代控制字符,以及如何处理无效字符。
3.lpMultiByteStr:指向将被转换字符串的字符。
4.cchMultiByte:指定由参数lpMultiByteStr指向的字符串中字节的个数。如果这个值为-1,字符串将被设定为以NULL为结束符的字符串,并且自动计算长度。
5.lpWideCharStr:指向接收被转换字符串的缓冲区。
6.cchWideChar:指定由参数lpWideCharStr指向的缓冲区的字节个数。若此值为零,函数返回缓冲区所必需的宽字符数,在这种情况下,lpWideCharStr中的缓冲区不被使用。
四、返回值:
1.如果函数运行成功,并且cchWideChar不为零,返回值是由lpWideCharStr指向的缓冲区中写入的宽字符数;
2.如果函数运行成功,并且cchMultiByte为零,返回值是接收到待转换字符串的缓冲区所需求的宽字符数大小。
3.如果函数运行失败,返回值为零。
五、注意: 指针lpMultiByteStr和lpWideCharStr必须不一样。
*****************************************/

/************************************
WideCharToMultiByte   
一、函数功能:该函数映射一个unicode字符串到一个多字节字符串。   
二、函数原型:int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPWSTR lpWideCharStr, int cchWideChar, LPCSTR lpMultiByteStr, int cchMultiByte, LPCSTR lpDefaultChar, PBOOL pfUsedDefaultChar );
三、参数说明:
1.CodePage:指定执行转换的编码。
2.dwFlags:一组位标记用以指出是否未转换成预作或宽字符(若组合形式存在),是否使用象形文字替代控制字符,以及如何处理无效字符。
3.lpWideCharStr:指向将被转换的unicode字符串。
4.cchWideChar:指定由参数lpWideCharStr指向的缓冲区的字符个数。
5.lpMultiByteStr:指向接收被转换字符串的缓冲区。
6.cchMultiByte:指定由参数lpMultiByteStr指向的缓冲区最大值(用字节来计量)。
7.lpDefaultChar:通常设为NULL。
8.pfUsedDefaultChar:通常设为NULL。
四、返回值:
1.如果函数运行成功,并且cchMultiByte不为零,返回值是由 lpMultiByteStr指向的缓冲区中写入的字节数;
2.如果函数运行成功,并且cchMultiByte为零,返回值是接收到待转换字符串的缓冲区所必需的字节数。
3.如果函数运行失败,返回值为零。
*****************************************/

#include <stdio.h>
#include <windows.h>
//GBK编码转换到UTF8编码
int GBKToUTF8(unsigned char * lpGBKStr,unsigned char * lpUTF8Str,int nUTF8StrLen)
{
    wchar_t * lpUnicodeStr = NULL;
    int nRetLen = 0;
    if(!lpGBKStr)  //如果GBK字符串为NULL则出错退出
        return 0;
    nRetLen = ::MultiByteToWideChar(CP_ACP,0,(char *)lpGBKStr,-1,NULL,NULL);  //获取转换到Unicode编码后所需要的字符空间长度
    lpUnicodeStr = new WCHAR[nRetLen + 1];  //为Unicode字符串空间
    nRetLen = ::MultiByteToWideChar(CP_ACP,0,(char *)lpGBKStr,-1,lpUnicodeStr,nRetLen);  //转换到Unicode编码
    if(!nRetLen)  //转换失败则出错退出
        return 0;
    nRetLen = ::WideCharToMultiByte(CP_UTF8,0,lpUnicodeStr,-1,NULL,0,NULL,NULL);  //获取转换到UTF8编码后所需要的字符空间长度
    
    if(!lpUTF8Str)  //输出缓冲区为空则返回转换后需要的空间大小
    {
        if(lpUnicodeStr)
            delete []lpUnicodeStr;
        return nRetLen;
    }
    
    if(nUTF8StrLen < nRetLen)  //如果输出缓冲区长度不够则退出
    {
        if(lpUnicodeStr)
            delete []lpUnicodeStr;
        return 0;
    }
    nRetLen = ::WideCharToMultiByte(CP_UTF8,0,lpUnicodeStr,-1,(char *)lpUTF8Str,nUTF8StrLen,NULL,NULL);  //转换到UTF8编码
    
    if(lpUnicodeStr)
        delete []lpUnicodeStr;
    
    return nRetLen;
}
// UTF8编码转换到GBK编码
int UTF8ToGBK(unsigned char * lpUTF8Str,unsigned char * lpGBKStr,int nGBKStrLen)
{
    wchar_t * lpUnicodeStr = NULL;
    int nRetLen = 0;
    if(!lpUTF8Str)  //如果UTF8字符串为NULL则出错退出
        return 0;
    nRetLen = ::MultiByteToWideChar(CP_UTF8,0,(char *)lpUTF8Str,-1,NULL,NULL);  //获取转换到Unicode编码后所需要的字符空间长度
    lpUnicodeStr = new WCHAR[nRetLen + 1];  //为Unicode字符串空间
    nRetLen = ::MultiByteToWideChar(CP_UTF8,0,(char *)lpUTF8Str,-1,lpUnicodeStr,nRetLen);  //转换到Unicode编码
    if(!nRetLen)  //转换失败则出错退出
        return 0;
    nRetLen = ::WideCharToMultiByte(CP_ACP,0,lpUnicodeStr,-1,NULL,NULL,NULL,NULL);  //获取转换到GBK编码后所需要的字符空间长度
    
    if(!lpGBKStr)  //输出缓冲区为空则返回转换后需要的空间大小
    {
        if(lpUnicodeStr)
            delete []lpUnicodeStr;
        return nRetLen;
    }
    
    if(nGBKStrLen < nRetLen)  //如果输出缓冲区长度不够则退出
    {
        if(lpUnicodeStr)
            delete []lpUnicodeStr;
        return 0;
    }
    nRetLen = ::WideCharToMultiByte(CP_ACP,0,lpUnicodeStr,-1,(char *)lpGBKStr,nRetLen,NULL,NULL);  //转换到GBK编码
    
    if(lpUnicodeStr)
        delete []lpUnicodeStr;
    
    return nRetLen;
}
//使用这两个函数的例子
int main()
{
    char cGBKStr[] = "我是中国人!";
    char * lpGBKStr = NULL;
    char * lpUTF8Str = NULL;
    FILE * fp = NULL;
    int nRetLen = 0;
    nRetLen = GBKToUTF8((unsigned char *)cGBKStr,NULL,NULL);
    printf("转换后的字符串需要的空间长度为:%d ",nRetLen);
    lpUTF8Str = new char[nRetLen + 1];
    nRetLen = GBKToUTF8((unsigned char *)cGBKStr,(unsigned char *)lpUTF8Str,nRetLen);
    if(nRetLen)
    {
        printf("GBKToUTF8转换成功!");
    }
    else
    {
        printf("GBKToUTF8转换失败!");
        goto Ret0;
    }
    
    fp = fopen("C:/GBK转UTF8.txt","wb");  //保存到文本文件
    fwrite(lpUTF8Str,nRetLen,1,fp);
    fclose(fp);
    
    getchar();  //先去打开那个文本文件看看,单击记事本的“文件”-“另存为”菜单,在对话框中看到编码框变为了“UTF-8”说明转换成功了
    nRetLen = UTF8ToGBK((unsigned char *)lpUTF8Str,NULL,NULL);  //再转回来
    printf("转换后的字符串需要的空间长度为:%d ",nRetLen);
    lpGBKStr = new char[nRetLen + 1];
    nRetLen = UTF8ToGBK((unsigned char *)lpUTF8Str,(unsigned char *)lpGBKStr,nRetLen);
    if(nRetLen)
    {
        printf("UTF8ToGBK转换成功! ");
    }
    else
    {
        printf("UTF8ToGBK转换失败! ");
        goto Ret0;
    }
    fp = fopen("C:/UTF8转GBK.txt","wb");  //保存到文本文件
    fwrite(lpGBKStr,nRetLen,1,fp);
    fclose(fp);
    
    getchar();  //再去打开文本文件看看,发现编码框又变为了“ANSI”说明转换成功了
Ret0:
    if(lpGBKStr)
        delete []lpGBKStr;
    
    if(lpUTF8Str)
        delete []lpUTF8Str;
        
    return 0;
}

以下是linux下的代码,从big5到utf8的例子

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <iconv.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SIZE 1024*1024

int Transcoding(char *fromcode,char *tocode,char *from,int from_len,char *to,int to_len)
{
	iconv_t cd;
	//form big5 to utf-8
	cd = iconv_open(tocode,fromcode);
	/*size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);
	此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。
 	*/
	if( iconv(cd,&from,&from_len,&to,&to_len) == -1 )
		printf("转换矢败!\n");
	else
		printf("转换成功!\n");
	iconv_close(cd);
	return SIZE-to_len;
}

//./test big5 utf-8 big5.txt utf8.txt
int main(int argc,char **argv[])
{
	char buf[SIZE];
	char result[SIZE];
	int fd_read,fd_write,n,m;
	fd_read = open(argv[3],O_RDONLY);
	fd_write = open(argv[4],O_WRONLY|O_CREAT);
	if(fd_read < 0)
		printf("不能打开源文件!\n");
	if(fd_write < 0)
		printf("不能打开目标文件!\n");
	n=read(fd_read,buf,SIZE);
	m=Transcoding(argv[1],argv[2],buf,n,result,SIZE);
	write(fd_write,result,m);
	fclose(fd_read);
	fclose(fd_write);
	return 0;
}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值