一套Windows上C/C++的编码转换函数

120 篇文章 6 订阅

在开发文档编辑器经常会遇到各种编码转换的问题要解决,虽然windows api有相关的函数。但是参数多,使用复杂每次都要查手册,很容易出错。

所以把常用的转换封装一下,用C的语法实现。支持c/c++

注意这些函数都会在堆中创建并返回新的字串,所以返回的字符串在使用完以后要显示销毁使用free(xxx)否则会造成内存泄漏。


第一条宏是取消烦人的VS编译器强制要求使用xxx_s函数的宏。如果在非VS编译器下会被自动忽略。


  1. #define _CRT_SECURE_NO_WARNINGS  
  2. #include <stdio.h>    
  3. #include <windows.h>    
  4. #include <locale.h>    
  5. #define BUFF_SIZE 1024    
  6.   
  7. wchar_t * ANSIToUnicode(const char* str)  
  8. {  
  9.     int textlen;  
  10.     wchar_t * result;  
  11.     textlen = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);  
  12.     result = (wchar_t *)malloc((textlen + 1)*sizeof(wchar_t));  
  13.     memset(result, 0, (textlen + 1)*sizeof(wchar_t));  
  14.     MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)result, textlen);  
  15.     return result;  
  16. }  
  17.   
  18. char * UnicodeToANSI(const wchar_t* str)  
  19. {  
  20.     char* result;  
  21.     int textlen;  
  22.     textlen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);  
  23.     result = (char *)malloc((textlen + 1)*sizeof(char));  
  24.     memset(result, 0, sizeof(char) * (textlen + 1));  
  25.     WideCharToMultiByte(CP_ACP, 0, str, -1, result, textlen, NULL, NULL);  
  26.     return result;  
  27. }  
  28.   
  29. wchar_t * UTF8ToUnicode(const char* str)  
  30. {  
  31.     int textlen;  
  32.     wchar_t * result;  
  33.     textlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);  
  34.     result = (wchar_t *)malloc((textlen + 1)*sizeof(wchar_t));  
  35.     memset(result, 0, (textlen + 1)*sizeof(wchar_t));  
  36.     MultiByteToWideChar(CP_UTF8, 0, str, -1, (LPWSTR)result, textlen);  
  37.     return result;  
  38. }  
  39.   
  40. char * UnicodeToUTF8(const wchar_t* str)  
  41. {  
  42.     char* result;  
  43.     int textlen;  
  44.     textlen = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);  
  45.     result = (char *)malloc((textlen + 1)*sizeof(char));  
  46.     memset(result, 0, sizeof(char) * (textlen + 1));  
  47.     WideCharToMultiByte(CP_UTF8, 0, str, -1, result, textlen, NULL, NULL);  
  48.     return result;  
  49. }  
  50. /*宽字符转换为多字符Unicode - ANSI*/  
  51. char* w2m(const wchar_t* wcs)  
  52. {  
  53.     int len;  
  54.     char* buf;  
  55.     len = wcstombs(NULL, wcs, 0);  
  56.     if (len == 0)  
  57.         return NULL;  
  58.     buf = (char *)malloc(sizeof(char)*(len + 1));  
  59.     memset(buf, 0, sizeof(char) *(len + 1));  
  60.     len = wcstombs(buf, wcs, len + 1);  
  61.     return buf;  
  62. }  
  63. /*多字符转换为宽字符ANSI - Unicode*/  
  64. wchar_t* m2w(const char* mbs)  
  65. {  
  66.     int len;  
  67.     wchar_t* buf;  
  68.     len = mbstowcs(NULL, mbs, 0);  
  69.     if (len == 0)  
  70.         return NULL;  
  71.     buf = (wchar_t *)malloc(sizeof(wchar_t)*(len + 1));  
  72.     memset(buf, 0, sizeof(wchar_t) *(len + 1));  
  73.     len = mbstowcs(buf, mbs, len + 1);  
  74.     return buf;  
  75. }  
  76.   
  77. char* ANSIToUTF8(const char* str)  
  78. {  
  79.     wchar_t * buf = ANSIToUnicode(str);  
  80.     char * ret =  UnicodeToUTF8(buf);  
  81.     free(buf);  
  82.     return ret;  
  83. }  
  84.   
  85. char* UTF8ToANSI(const char* str)  
  86. {  
  87.     wchar_t * buf = UTF8ToUnicode(str);  
  88.     char * ret = UnicodeToANSI(buf);  
  89.     free(buf);  
  90.     return ret;  
  91. }  
  92.   
  93. int main()  
  94. {  
  95.     ///*使用wcstombs和mbstowcs之前必须调用setlocale,以便决定内码*/  
  96.     //setlocale(LC_ALL, ".936");  
  97.     ///*假定有一个Unicode(UTF-16LE)编码的文件,将其打开,重新编码为ANSI,写入aa.txt中,再继续编码回Unicode,写入aw.txt中*/  
  98.     ///*如果不存在a.txt文件,则程序出错,没有做错误处理*/  
  99.     //char* filename = "a.txt";  
  100.     //char* filenamea = "aa.txt";  
  101.     //char* filenamew = "aw.txt";  
  102.     //FILE*     input = fopen(filename, "rb");  
  103.     //FILE*     inputa = fopen(filenamea, "wb");  
  104.     //FILE*     inputw = fopen(filenamew, "wb");  
  105.     //wchar_t * buf;  
  106.     ///*BOE设置,UTF-16LE的BOE为FEFF,如果不先将其读取出来,wcstombs会调用失败*/  
  107.     //fgetwc(input);  
  108.     //fputwc(0xFEFF, inputw);  
  109.     ///*开始读取文件*/  
  110.     //while (!feof(input))  
  111.     //{  
  112.     //  buf = (wchar_t *)malloc(sizeof(wchar_t)*BUFF_SIZE);  
  113.     //  memset(buf, 0, sizeof(wchar_t) * BUFF_SIZE);  
  114.     //  fgetws(buf, BUFF_SIZE, input);  
  115.     //  fputs(w2m(buf), inputa);  
  116.     //  fputws(m2w(w2m(buf)), inputw);  
  117.     //}  
  118.     ///*后续处理*/  
  119.     //fclose(input);  
  120.     //fclose(inputa);  
  121.     //fclose(inputw);  
  122.     //free(buf);  
  123.     char str[] = "多选控件";  
  124.     char * buf = ANSIToUTF8(str);  
  125.     BYTE pbuf[255];  
  126.     memcpy(pbuf, buf, strlen(buf) + 1);  
  127.     int i = 0;  
  128.     char outbuff[BUFF_SIZE];  
  129.     FILE*     outfile = fopen("out.txt""wb");  
  130.     while (pbuf[i])  
  131.     {  
  132.         sprintf(outbuff, "0x%02x, ", pbuf[i++]);  
  133.         fputs(outbuff, outfile);  
  134.     }  
  135.     sprintf(outbuff, "0x00}");  
  136.     fputs(outbuff, outfile);  
  137.     fclose(outfile);  
  138.   
  139.     free(buf);  
  140.     return 0;  
  141. }  
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <windows.h>  
#include <locale.h>  
#define BUFF_SIZE 1024  

wchar_t * ANSIToUnicode(const char* str)
{
	int textlen;
	wchar_t * result;
	textlen = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
	result = (wchar_t *)malloc((textlen + 1)*sizeof(wchar_t));
	memset(result, 0, (textlen + 1)*sizeof(wchar_t));
	MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)result, textlen);
	return result;
}

char * UnicodeToANSI(const wchar_t* str)
{
	char* result;
	int textlen;
	textlen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
	result = (char *)malloc((textlen + 1)*sizeof(char));
	memset(result, 0, sizeof(char) * (textlen + 1));
	WideCharToMultiByte(CP_ACP, 0, str, -1, result, textlen, NULL, NULL);
	return result;
}

wchar_t * UTF8ToUnicode(const char* str)
{
	int textlen;
	wchar_t * result;
	textlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
	result = (wchar_t *)malloc((textlen + 1)*sizeof(wchar_t));
	memset(result, 0, (textlen + 1)*sizeof(wchar_t));
	MultiByteToWideChar(CP_UTF8, 0, str, -1, (LPWSTR)result, textlen);
	return result;
}

char * UnicodeToUTF8(const wchar_t* str)
{
	char* result;
	int textlen;
	textlen = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
	result = (char *)malloc((textlen + 1)*sizeof(char));
	memset(result, 0, sizeof(char) * (textlen + 1));
	WideCharToMultiByte(CP_UTF8, 0, str, -1, result, textlen, NULL, NULL);
	return result;
}
/*宽字符转换为多字符Unicode - ANSI*/
char* w2m(const wchar_t* wcs)
{
	int len;
	char* buf;
	len = wcstombs(NULL, wcs, 0);
	if (len == 0)
		return NULL;
	buf = (char *)malloc(sizeof(char)*(len + 1));
	memset(buf, 0, sizeof(char) *(len + 1));
	len = wcstombs(buf, wcs, len + 1);
	return buf;
}
/*多字符转换为宽字符ANSI - Unicode*/
wchar_t* m2w(const char* mbs)
{
	int len;
	wchar_t* buf;
	len = mbstowcs(NULL, mbs, 0);
	if (len == 0)
		return NULL;
	buf = (wchar_t *)malloc(sizeof(wchar_t)*(len + 1));
	memset(buf, 0, sizeof(wchar_t) *(len + 1));
	len = mbstowcs(buf, mbs, len + 1);
	return buf;
}

char* ANSIToUTF8(const char* str)
{
	wchar_t * buf = ANSIToUnicode(str);
	char * ret =  UnicodeToUTF8(buf);
	free(buf);
	return ret;
}

char* UTF8ToANSI(const char* str)
{
	wchar_t * buf = UTF8ToUnicode(str);
	char * ret = UnicodeToANSI(buf);
	free(buf);
	return ret;
}

int main()
{
	///*使用wcstombs和mbstowcs之前必须调用setlocale,以便决定内码*/
	//setlocale(LC_ALL, ".936");
	///*假定有一个Unicode(UTF-16LE)编码的文件,将其打开,重新编码为ANSI,写入aa.txt中,再继续编码回Unicode,写入aw.txt中*/
	///*如果不存在a.txt文件,则程序出错,没有做错误处理*/
	//char* filename = "a.txt";
	//char* filenamea = "aa.txt";
	//char* filenamew = "aw.txt";
	//FILE*     input = fopen(filename, "rb");
	//FILE*     inputa = fopen(filenamea, "wb");
	//FILE*     inputw = fopen(filenamew, "wb");
	//wchar_t * buf;
	///*BOE设置,UTF-16LE的BOE为FEFF,如果不先将其读取出来,wcstombs会调用失败*/
	//fgetwc(input);
	//fputwc(0xFEFF, inputw);
	///*开始读取文件*/
	//while (!feof(input))
	//{
	//	buf = (wchar_t *)malloc(sizeof(wchar_t)*BUFF_SIZE);
	//	memset(buf, 0, sizeof(wchar_t) * BUFF_SIZE);
	//	fgetws(buf, BUFF_SIZE, input);
	//	fputs(w2m(buf), inputa);
	//	fputws(m2w(w2m(buf)), inputw);
	//}
	///*后续处理*/
	//fclose(input);
	//fclose(inputa);
	//fclose(inputw);
	//free(buf);
	char str[] = "多选控件";
	char * buf = ANSIToUTF8(str);
	BYTE pbuf[255];
	memcpy(pbuf, buf, strlen(buf) + 1);
	int i = 0;
	char outbuff[BUFF_SIZE];
	FILE*     outfile = fopen("out.txt", "wb");
	while (pbuf[i])
	{
		sprintf(outbuff, "0x%02x, ", pbuf[i++]);
		fputs(outbuff, outfile);
	}
	sprintf(outbuff, "0x00}");
	fputs(outbuff, outfile);
	fclose(outfile);

	free(buf);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值