Visual C++编写控制台程序是ANSI编码的,然而这种编码比较过时,因此编程时常与其它两种字符串打交道:
一种是宽字符,一般WinAPI、COM、.NET使用这种字符串;
一种是UTF-8,一般来自网络数据。
这几种编码之间的转换一般使用MultiByteToWideChar和WideCharToMultiByte函数。
但是这个函数使用比较麻烦,特别是UTF-8,需要分配缓冲区,转码两次,再释放掉缓冲区。
提供的常用转码函数:
to_wide ANSI转换为宽字符
from_wide 宽字符转换为ANSI
to_utf8 ANSI转换为UTF-8
from_utf8 UTF-8转换为ANSI
utf8_to_wide UTF-8转换为宽字符
utf8_from_wide 宽字符转换为UTF-8
以上函数的参数列表基本相同(均为3个),使用方法(以to_utf8为例):
int retval = to_utf8(NULL, 0, srcstr); // 返回所需缓冲区大小(以字符计)
int retval = to_utf8(outbuf, outbufsize, srcstr); // 成功返回已写入大小(以字符计),失败返回0
另有一个使用堆内存保存结果的to_utf8_alloc函数,使用方法如下:
char *result = to_utf8_alloc(srcstr);
free(result);
由于from_utf8可以安全地执行就地转换(ANSI永远比UTF-8小),没有必要提供from_utf8_alloc函数。
如果需要这个功能的话,可以使用接下来要讲到的cp_to_cp_alloc实现。
以上常用转码函数是由以下六个通用转码函数封装得到的:
cp_to_wide 指定代码页转换为宽字符
cp_from_wide 宽字符转换为指定代码页
cp_to_wide_alloc 指定代码页转换为宽字符并返回包含结果的堆内存指针
cp_from_wide_alloc 宽字符转换为指定代码页并返回包含结果的堆内存指针
cp_to_cp 转换代码页
cp_to_cp_alloc 转换代码页并返回包含结果的堆内存指针
使用示例如下所示(使用了MessageBoxW显示宽字符串,因此需要#include <windows.h>):
<code class="lang-cpp">#pragma comment(lib, "user32.lib") // MessageBoxW
#include <stdio.h>
#include <stdlib.h>
#include <windows.h> // MessageBoxW
#include "../zm.h"
int main()
{
char ansi_str[] = "我是中文示例12345678";
wchar_t wide_str[] = L"我是\u315D\u314F\uB204\uB77C12345678";
char utf8_a[256] = "";
char utf8_b[256] = "";
char ansi_a[256] = "";
char ansi_b[256] = "";
char ansi_c[256] = "";
wchar_t wide_a[256] = L"";
wchar_t wide_b[256] = L"";
printf("ansi_str=%s\n", ansi_str); // 显示原始ANSI字符串
printf("wide_str=[see MessageBox]\n");
MessageBoxW(NULL, wide_str, L"wide_str", MB_OK); // 显示原始宽字符串
to_utf8(utf8_a, 256, ansi_str); // ANSI转码到UTF-8
printf("utf8_a=%s [from ansi_str]\n", utf8_a);
char *utf8_alloc = to_utf8_alloc(ansi_str); // ANSI使用堆内存转码到UTF-8
printf("utf8_alloc=%s [from ansi_str]\n", utf8_alloc);
free(utf8_alloc);
utf8_from_wide(utf8_b, 256, wide_str); // 宽字符转码到UTF-8
printf("utf8_b=%s [from wide_str]\n", utf8_b);
from_wide(ansi_a, 256, wide_str); // 宽字符转码到ANSI
printf("ansi_a=%s [from wide_str]\n", ansi_a);
from_utf8(ansi_b, 256, utf8_a); // UTF-8转码到ANSI(1)
printf("ansi_b=%s [from utf8_a]\n", ansi_b);
from_utf8(ansi_c, 256, utf8_b); // UTF-8转码到ANSI(2)
printf("ansi_c=%s [from utf8_b]\n", ansi_c);
to_wide(wide_a, 256, ansi_str); // ANSI转码到宽字符
printf("wide_a=[see MessageBox] [from ansi_str]\n");
MessageBoxW(NULL, wide_a, L"wide_a [from ansi_str]", MB_OK);
utf8_to_wide(wide_b, 256, utf8_b); // UTF-8转码到宽字符
printf("wide_b=[see MessageBox] [from utf8_b]\n");
MessageBoxW(NULL, wide_b, L"wide_b [from utf8_b]", MB_OK);
return 0;
}</windows.h></stdlib.h></stdio.h></code>
运行结果:
200字以内,仅用于支线交流,主线讨论请采用回复功能。