写在前面
本文针对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++;} elsecnt["其它字符"]++;}for (map<string, int>::iterator it = cnt.begin(); it!=cnt.end(); it++) {printf("%s个数:%d\n", (it->first).c_str(), it->second);}return 0;}