C++处理中文字符

问题描述:

c++ 中 char*/string 形式的字符串无法正确的对中文字符串进行处理(如 find, strlen, substr 等常规操作) 。

比如当你在char* 中 find 英文逗号时,有可能匹配的不只是逗号,还找到了某个汉字的一个字节,而你无法在char*中区分它们。

问题原因:

中文字符长度不固定,按字节处理往往出现乱码或错误分割。在unicode中每个中文为2个字节,而中文中间夹杂的英文和半角标点则仍然是1个字节。

解决方案:

构造三层逻辑结构:输入层、逻辑处理层、输出层。

-- 输入层接收char*输入,并将其转换为wchar*.

-- 逻辑处理层在 wchar* 或 wstring 的基础上进行字符串操作,此时操作最小单位为中文字符,不会再有乱码。

-- 输出层将wchar*的结果再次转换为char* ,返回给外部。

这样,对外部来说,仍然是输入char*, 输出char*, 但在这个过程中不再有分割汉字的操作或乱码。

核心转换代码:

  1 #include <iostream>
  2 
  3 #include <string>
  4 
  5 using namespace std;
  6 
  7  
  8 
  9 wchar_t* MBCS2Unicode(wchar_t * buff, const char * str)
 10 
 11 {
 12 
 13     wchar_t * wp = buff;
 14 
 15     char * p = (char *)str;
 16 
 17     while (*p)
 18 
 19     {
 20 
 21         if (*p & 0x80)
 22 
 23         {
 24 
 25             *wp = *(wchar_t *)p;
 26 
 27             p++;
 28 
 29         }
 30 
 31         else {
 32 
 33             *wp = (wchar_t)*p;
 34 
 35         }
 36 
 37         wp++;
 38 
 39         p++;
 40 
 41     }
 42 
 43     *wp = 0x0000;
 44 
 45     return buff;
 46 
 47 }
 48 
 49  
 50 
 51 char * Unicode2MBCS(char * buff, const wchar_t * str)
 52 
 53 {
 54 
 55     wchar_t * wp = (wchar_t *)str;
 56 
 57     char * p = buff, *tmp;
 58 
 59     while (*wp) {
 60 
 61         tmp = (char *)wp;
 62 
 63         if (*wp & 0xFF00) {
 64 
 65             *p = *tmp;
 66 
 67             p++; tmp++;
 68 
 69             *p = *tmp;
 70 
 71             p++;
 72 
 73         }
 74 
 75         else {
 76 
 77             *p = *tmp;
 78 
 79             p++;
 80 
 81         }
 82 
 83         wp++;
 84 
 85     }
 86 
 87     *p = 0x00;
 88 
 89     return buff;
 90 
 91 }
 92 
 93  
 94 
 95 wstring str2wstr(string str)
 96 
 97 {
 98 
 99     size_t len = str.size();
100 
101     wchar_t * b = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
102 
103     MBCS2Unicode(b, str.c_str());
104 
105     wstring r(b);
106 
107     free(b);
108 
109     return r;
110 
111 }
112 
113 int wputs(const wchar_t * wstr);
114 
115 int wputs(wstring wstr)
116 
117 {
118 
119     wputs(wstr.c_str());
120 
121     return 0;
122 
123 }
124 
125  
126 
127 int wputs(const wchar_t * wstr)
128 
129 {
130 
131     int len = wcslen(wstr);
132 
133     char * buff = (char *)malloc((len * 2 + 1) * sizeof(char));
134 
135     Unicode2MBCS(buff, wstr);
136 
137     printf("%s", buff);
138 
139     free(buff);
140 
141     return 0;
142 
143 }
144 
145  
146 
147 string wstr2str(wstring wstr)
148 
149 {
150 
151     size_t len = wstr.size();
152 
153     char * b = (char *)malloc((2 * len + 1) * sizeof(char));
154 
155     Unicode2MBCS(b, wstr.c_str());
156 
157     string r(b);
158 
159     free(b);
160 
161     return r;
162 
163 }
164 
165  
166 
167 int main()
168 
169 {
170 
171     //输入层:接收char*输入,并将其转换为wchar*
172 
173     string input = "今天你在武汉!!";
174 
175     string temp = "在";
176 
177     
178 
179     //逻辑层在whcar*或wstring的基础上进行字符串操作,此时操作最小单位为中文字符,不会再有乱码。
180 
181     wstring buff = str2wstr(input);
182 
183     wstring temp_buff = str2wstr(temp);
184 
185     cout << "input的中文个数:"<<wcslen(buff.c_str()) << "   temp的中文个数:" << wcslen(temp_buff.c_str()) << endl;
186 
187     cout << "判断input第三个是否是'在':" << (buff[3] == temp_buff[0]) << endl;;
188 
189  
190 
191     //输出层将wchar*的结果再次转换为char*,返回给外部
192 
193     wputs(buff);
194 
195  
196 
197     return 0;
198 
199 }

转自:https://blog.csdn.net/qq_30263737/article/details/85340022