Win32 - 04 编码转换CRT版本
既然不同的平台有字符集的差别,那么在不同平台之间传递数据就需要进行“编码转换”。
本例介绍了如何利用C标准库函数对UNICODE编码和ASCII编码进行转换,转换目标是将ASCII编码(或本地编码,例如GBK编码)字符/字符串与UNICODE编码字符串进行相互转化。
1 | #include <tchar.h> |
2 | #include <locale.h> |
3 | #include <stdio.h> |
4 | #include <errno.h> |
5 | #include <stdlib.h> |
6 | |
7 | #define BUF_LEN 512 |
8 | |
9 | int _tmain(int argc, TCHAR* argv[]) |
10 | { |
11 | // 定义UNICODE编码字符 |
12 | wchar_t wc = L'大'; |
13 | // 定义ASCII/GBK编码字符缓冲(其容量可以存放一个中文字符) |
14 | char szChar[3] = ""; |
15 | int i, nError; |
16 | |
17 | // 定义UNICODE编码字符串 |
18 | const wchar_t* lpcszW = L"Hello, 大家好!"; |
19 | // 定义指向ASCII编码字符串的指针 |
20 | char* lpszBuffer = NULL; |
21 | // 定义指向UNICODE编码字符串的指针 |
22 | wchar_t* lpwcsBuffer = NULL; |
23 | // 定义字符串长度变量 |
24 | size_t nLength = 0; // size_t映射为unsigned int类型 |
25 | |
26 | // 设置当前语言环境(中文) |
27 | _tsetlocale(LC_ALL, _T("zhi")); |
28 | |
29 | // 将UNICODE字符转为对应的ASCII/GBK字符串 |
30 | // (一个UNICODE字符占据2个字节,加上/0共三个字节) |
31 | nError = wctomb_s(&i, // 返回转换后占用的字节数 |
32 | szChar, // 保存转换结果的缓冲数组 |
33 | 3, // 保存转换结果的缓冲数组长度 |
34 | wc // 要转换的UNICODE字符 |
35 | ); |
36 | // wctomb_s函数返回0表示运行正确,否则表示运行失败 |
37 | if (nError == 0) { |
38 | printf("转换后的字符串为:%s", szChar); |
39 | } else { |
40 | _tprintf(_T("字符转化失败")); |
41 | } |
42 | |
43 | // 给ASCII/GBK缓冲内存放新汉字 |
44 | strcpy_s(szChar, 3, "小"); |
45 | // 将一个ASCII/GBK字符串转化为UNICODE字符 |
46 | nError = mbtowc(&wc, // 指向UNICODE字符变量的指针 |
47 | szChar, // 指向要转换ASCII/GBK字符串的指针 |
48 | strlen(szChar) // 要转换ASCII/GBK字符串长度 |
49 | ); |
50 | |
51 | // mbtowc函数如果运行正确,返回转化结果的字符串长度;返回0表示参数1为/0字符;返回-1表示失败 |
52 | if (nError > 0) { |
53 | wprintf(L"/n转换后的字符为:%c", wc); |
54 | } else { |
55 | _tprintf(_T("/n字符转化失败")); |
56 | } |
57 | |
58 | // UNICODE编码转为ASCII编码 |
59 | // 第一步,获取缓冲区长度(不包括/0字符) |
60 | nLength = wcstombs( |
61 | NULL, // 指向待转化的ASCII/GBK字符串缓冲的指针,此时填NULL |
62 | lpcszW, // 要转化的UNICODE字符串指针 |
63 | 0 // 参数1缓冲区长度,单位字节 |
64 | ) + 1; // 由于函数返回的ASCII/GBK缓冲区长度不包括/0字符,所以结果要加1 |
65 | |
66 | if (nLength == -1 && errno == EILSEQ) { |
67 | _tprintf("/n转换失败"); |
68 | } else { |
69 | // 第二步,分配缓冲区 |
70 | if (lpszBuffer = (char*)malloc(nLength)) { |
71 | |
72 | // 第三步,转化字符串,再次调用wcstombs函数, |
73 | // 此时第1个参数填写上一步分配的缓冲区指针, |
74 | // 第3个参数填写缓冲区长度 |
75 | wcstombs(lpszBuffer, lpcszW, nLength); |
76 | printf("/n转化后的字符串为:%s", lpszBuffer); |
77 | |
78 | // ASCII编码转为UNICODE编码,步骤和解释类似 |
79 | // 于与UNICODE编码转为ASCII编码 |
80 | |
81 | // 第一步,获取缓冲区长度 |
82 | nLength = mbstowcs(NULL, lpszBuffer, 0) + 1; |
83 | if (nLength == -1 && errno == EILSEQ) { |
84 | _tprintf("/n转换失败"); |
85 | } else { |
86 | |
87 | // 第二步,分配缓冲区 |
88 | if (lpwcsBuffer = (wchar_t*)malloc(nLength * sizeof(wchar_t))) { |
89 | |
90 | // 第三步,转化字符串 |
91 | mbstowcs(lpwcsBuffer, lpszBuffer, nLength); |
92 | wprintf(L"/n转化后的字符串为:%s", lpwcsBuffer); |
93 | |
94 | free(lpwcsBuffer); |
95 | } else { |
96 | _tprintf(_T("/n内存分配失败")); |
97 | } |
98 | } |
99 | free(lpszBuffer); |
100 | } else { |
101 | _tprintf(_T("/n内存分配失败")); |
102 | } |
103 | } |
104 | |
105 | _tprintf(_T("/n")); |
106 | _tsystem(_T("pause")); |
107 | return 0; |
108 | } |