赞
踩
windows下进行C/C++编程时,需要处理各种各样的网络数据、文本数据,由于数据编码可能不一样,这时就需要对数据进行转码,否则程序将无法正常工作。
常用的数据编码有GBK(GB2312)、UTF-8、UNICODE,具体的字符集相关知识我会单独写一篇文档进行描述,下面列出这三种字符集相互之间互转的封装函数。
这里使用了windows的两个库函数MultiByteToWideChar、WideCharToMultiByte
涉及到的头文件:
函数所在头文件:Windows.h
#include <Windows.h>
wchar_t类型所需头文件:wchar.h
#include <wchar.h>
/********************************************************************* 函数名 : multiByteToUnicode 功能 : 将多字节字符串转换为Unicode字符串(例如:gbk字符串转为unicode字符串;utf-8字符串转为unicode字符串) 参数 : multiByteStr:指向待转换的字符串的缓冲区 multiByteStrLen:指定由参数multiByteStr指向的字符串中字节的个数 multiByteCharsetFlag:指定执行转换的多字节字符所使用的字符集,可选值有CP_ACP(gbk/gb2312)、CP_UTF8(utf-8) unicodeStr:指向接收被转换字符串的缓冲区 unicodeStrLen:指定由参数unicodeStr指向的缓冲区的字节数 返回值 : 成功时,返回解析好的字节个数,错误时,返回相应错误码(-1:待转换的字符串为空;-2:待转换的字符串的长度小于等于0;-3:字符集设置不合理,必须 是CP_ACP和CP_UTF8之一;-4:接收转换字符串缓存区为空;-5:接收转换字符串缓存区长度小于等于0;-6:接收被转换字符串的缓冲区小于实际需要的字节 数) 日期 : 2018-09-26 作者 : xxx *********************************************************************/ int multibyteToUnicode(const char *multiByteStr,int multiByteStrLen,UINT multiByteCharsetFlag,char *unicodeStr,int unicodeStrLen) { if (multiByteStr==NULL)//原始字符串为空 { return -1; } if (multiByteStrLen<=0)//原始字符串长度小于等于0 { return -2; } if (multiByteCharsetFlag!=CP_ACP && multiByteCharsetFlag!=CP_UTF8)//原始字符串字符集标识既不是GBK/GB2312又不是UTF-8 { return -3; } if (unicodeStr==NULL)//用于存放unicode串的缓存区为空 { return -4; } if (unicodeStrLen<=0)//用于存放unicode串的缓存区的长度小于等于0 { return -5; } int requiredUnicode=MultiByteToWideChar(multiByteCharsetFlag,0,multiByteStr,multiByteStrLen,NULL,0);//此种情况用来获取转换所需的wchar_t的个数 if(sizeof(WCHAR)*requiredUnicode>unicodeStrLen)//接收被转换字符串的缓冲区小于实际需要的字节数 { return -6; } WCHAR *tmp=new WCHAR[requiredUnicode];//动态分配unicode临时缓存区 wmemset(tmp,0,requiredUnicode);//将临时缓存区数据清零 //执行真实转换,并将转换后的unicode串写到tmp缓存区 int parsedUnicode=MultiByteToWideChar(multiByteCharsetFlag,0,multiByteStr,multiByteStrLen,tmp,requiredUnicode); if (parsedUnicode!=requiredUnicode)//判断真实解析的unicode字符数和分配的字符数是否一致 { delete []tmp; tmp=NULL; return -7; } memset(unicodeStr,0,unicodeStrLen);//将目标unicode缓存区清零 memcpy(unicodeStr,tmp,sizeof(WCHAR)*requiredUnicode);//将数据由临时缓存区拷贝到目标unicode缓存区 delete [] tmp;//释放空间 tmp=NULL; return sizeof(WCHAR)*requiredUnicode;//返回解析好的总字节数 }
/********************************************************************* 函数名 : unicodeToMultibyte 功能 : 将Unicode字符串转换为多字节字符串(例如:将unicode字符串转换为gb2312/utf-8编码的字符串) 参数 : unicodeStr:指向待转换的unicode字符串的缓冲区,该字符串必须是小端字节序 unicodeStrLen:指定由参数unicodeStr指向的字符串中字节的个数 multiByteStr:指向接收被转换字符串的缓冲区 multiByteStrLen:指定由参数multiByteStr指向的缓冲区的字节数 multiByteCharsetFlag:指定目标字符串所使用的字符集,可选值有CP_ACP(gbk/gb2312)、CP_UTF8(utf-8) 返回值 : 成功时,返回解析好的字节个数,错误时,返回相应错误码(-1:待转换的字符串为空;-2:待转换的字符串的长度小于等于0;-3:接收转换字符串缓存区为 空;-4:接收转换字符串缓存区长度小于等于0;-5:字符集设置不合理,必须是CP_ACP和CP_UTF8之一;-6:接收被转换字符串的缓冲区小于实际需要的字节数) 日期 : 2018-09-27 作者 : xxx *********************************************************************/ int unicodeToMultibyte(const char *unicodeStr,int unicodeStrLen,char *multiByteStr,int multiByteStrLen,UINT multiByteCharsetFlag) { if (unicodeStr==NULL)//原始unicode字符串为空 { return -1; } if (unicodeStrLen<=0)//原始unicode字符串的长度小于等于0 { return -2; } if (multiByteStr==NULL)//用于存放多字节字符串的缓存区为空 { return -3; } if (multiByteStrLen<=0)//用于存放多字节字符串的缓存区的长度小于等于0 { return -4; } if (multiByteCharsetFlag!=CP_ACP && multiByteCharsetFlag!=CP_UTF8)//目标字符串所使用的字符集既不是CP_ACP(gbk/gb2312)又不是CP_UTF8(utf-8) { return -5; } WCHAR *tmp=new WCHAR[unicodeStrLen/2];//动态分配用于存放原始Unicode字符串的临时缓存区 wmemset(tmp,0,unicodeStrLen/2);//将临时缓存区清零 memcpy(tmp,unicodeStr,unicodeStrLen);//将原始Unicode字符串拷贝到临时缓存区 int requiredByte=WideCharToMultiByte(multiByteCharsetFlag,0,tmp,unicodeStrLen/2,NULL,0,NULL,NULL);//获取用于存放目标字符串的字节数 if (requiredByte>multiByteStrLen)//接收被转换字符串的缓冲区小于实际需要的字节数 { delete []tmp; tmp=NULL; return -6; } memset(multiByteStr,0,multiByteStrLen);//将目标缓存区清零 //执行真正转换,将转换后的多字节字符串存放到目标缓存区中,并返回实际解析的字节数 int parsedByte=WideCharToMultiByte(multiByteCharsetFlag,0,tmp,unicodeStrLen/2,multiByteStr,multiByteStrLen,NULL,NULL); if (parsedByte!=requiredByte)//实际解析的字节数不正确 { delete []tmp; tmp=NULL; return -7; } delete []tmp;//释放临时缓存区 tmp=NULL; return parsedByte;//返回解析好的总字节数 }
/********************************************************************* 函数名 : gbkToUtf8 功能 : 将gbk编码的字符串转换为utf8编码的字符串 参数 : gbkstr:指向待转换的gbk字符串的缓冲区 gbkstrlen:指定由参数gbkstr指向的字符串中字节的个数 utf8str:指向接收被转换字符串的缓冲区 utf8strlen:指定由参数utf8str指向的缓冲区的字节数 返回值 : 成功时,返回解析好的字节个数,错误时,返回相应错误码(-1:字符串为空或长度小于等于0;-2:gbk转unicode失败;-3:unicode转utf-8失败) 日期 : 2018-09-27 作者 : xxx *********************************************************************/ int gbkToUtf8(const char * gbkstr,int gbkstrlen,char * utf8str,int utf8strlen) { if (gbkstr==NULL || gbkstrlen<=0 || utf8str==NULL || utf8strlen<=0)//字符串为空或长度小于等于0 { return -1; } char *unicodestr=new char[2*gbkstrlen];//分配缓存区,长度为gbk字符串长度的2倍 int unicodebytes=multibyteToUnicode(gbkstr,gbkstrlen,CP_ACP,unicodestr,2*gbkstrlen);//gbk转unicode if (unicodebytes<0)//gbk转unicode失败 { delete [] unicodestr; unicodestr=NULL; return -2; } int utf8bytes=unicodeToMultibyte(unicodestr,unicodebytes,utf8str,utf8strlen,CP_UTF8);//unicode转utf-8 if (utf8bytes<0)//unicode转utf-8失败 { delete [] unicodestr; unicodestr=NULL; return -3; } delete [] unicodestr;//释放内存 unicodestr=NULL; return utf8bytes;//返回解析好的总utf8字节数 }
/********************************************************************* 函数名 : utf8ToGbk 功能 : 将utf8编码的字符串转换为gbk编码的字符串 参数 : utf8str:指向待转换的utf8字符串的缓冲区 utf8strlen:指定由参数utf8str指向的字符串中字节的个数 gbkstr:指向接收被转换字符串的缓冲区 gbkstrlen:指定由参数gbkstr指向的缓冲区的字节数 返回值 : 成功时,返回解析好的字节个数,错误时,返回相应错误码(-1:字符串为空或长度小于等于0;-2:utf8转unicode失败;-3:unicode转gbk失败) 日期 : 2018-09-27 作者 : xxx *********************************************************************/ int utf8ToGbk(const char * utf8str,int utf8strlen,char * gbkstr,int gbkstrlen) { if (utf8str==NULL || utf8strlen<=0 || gbkstr==NULL || gbkstrlen<=0)//字符串为空或长度小于等于0 { return -1; } char *unicodestr=new char[2*utf8strlen];//分配缓存区,长度为utf8字符串长度的2倍 int unicodebytes=multibyteToUnicode(utf8str,utf8strlen,CP_UTF8,unicodestr,2*utf8strlen);//utf8转unicode if (unicodebytes<0)//utf8转unicode失败 { delete [] unicodestr; unicodestr=NULL; return -2; } int gbkbytes=unicodeToMultibyte(unicodestr,unicodebytes,gbkstr,gbkstrlen,CP_ACP);//unicode转GBK if (gbkbytes<0)//unicode转gbk失败 { delete [] unicodestr; unicodestr=NULL; return -3; } delete [] unicodestr; unicodestr=NULL; return gbkbytes;//返回解析好的gbk字节数 }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。