写在前面
本文针对GBK
编码进行编程,可以右键控制台选择属性查看。
若是UTF-8或其他编码,可以查询相对应的编码表,参考本文思路进行编程。
判断中文字符
- 首先,我们要知道输入一个中文字符,如果是
GBK编码
,那么要用两字节
进行存储,如果拿string
进行存储,那么字符串长度其实为2
,s[0]是高字节而s[1]是低字节
(此处涉及到内存存储,请参考大小端模式)。 - 有了前置知识就好办了,我们判断中文字符的阻碍其实就是
中文字符存储字节数的不确定
和每个字节存储范围的不确定
。如果我们能知道编码是什么,那么上面两个问题就都解决了。 - 搜索资料可知
GBK编码
范围为0x8140到0xFEFE
(这个0x
其实是16进制表示的意思,两个十六进制位,就是8位也就是一个字节)。说人话:用16进制
表示的话,高字节范围从81
到FE
,低字节范围从40
到FE
,若不符合则不是GBK中文字符。
参考代码
这个编程风格是为了缩格演示思路,并不规范,请见谅。。。
#include <iostream>
#include <map>
using namespace std;
int main(){
cout<<"请输入字符串:"<<endl;
string s;
getline(cin, s); //获取一行输入
map<string, int> cnt; //用于统计
for (int i=0; i<s.length(); i++) {
if ((s[i]>='a'&&s[i]<='z') || (s[i]>='A'&&s[i]<='Z'))
cnt["英文字母"]++;
else if (s[i]>='0' && s[i]<='9')
cnt["数字"]++;
else if (s[i] == ' ')
cnt["空格"]++;
else if(i+1<s.length() && //防止越界
((unsigned char)s[i]>=0x81&&(unsigned char)s[i]<=0xFE&& //高位
(unsigned char)s[i+1]>=0x40&&(unsigned char)s[i+1]<=0xFE)){ //低位
//使用unsigned char是因为unsigned不会变成负值,这样方便判断
cnt["中文字符"]++;
i++;
} else
cnt["其它字符"]++;
}
for (map<string, int>::iterator it = cnt.begin(); it!=cnt.end(); it++) {
printf("%s个数:%d\n", (it->first).c_str(), it->second);
}
return 0;
}