前几天看到一道统计输入文本中的文字的数目的题,一开始以为是统计英文,后来才发现是统计中文汉字的数目(毕竟统计英文字母这种事,咱也会),原题如下:
题目上有两个要求:输入、统计
以C语言为例:
要求一:输入一页文字(so easy , man),采用数组存储,fgets()函数输入。
要求二:其实统计数字和空格很简单,因为数字和空格都可以由一个字节来表示,如果这个字节的ASCII码在数字的ASCII码范围中或者等于空格,结果就很明确了。
关键是统计文字。
我们平时使用的是全角字符,大家都知道,半角字符几乎都能用一个ASCII码表示,但是汉字却不能,它需要使用两个或者多个字节才能正确表示。一个汉字跟全角字符在内存中存储的时候占两个字节,强行把这每一个字节当ASCII码来看的话,它的值是大于128的(但是对于计算机来说,最高位是符号位,也就是说,这个字节的ASCII码会被计算机解释成负数,这个可以用来判断是不是全角字符),也就是说每个字节的最高位是1,落在了扩展的ASCII码表上。GBK编码和这种处理方式类似,它也是采用两个字节来存储,所以判断汉字的时候,可以用这个全角字符的GB码(国标码)来判断。
GB码相关资料:https://www.cnblogs.com/winnxm/archive/2009/12/15/1625088.html
https://segmentfault.com/a/1190000023809482
判断是否存在全角字符:
如上述,两个字节的ASCII码小于0,则存在。
if(char[0] < 0 && char[1] < 0)
判断是否为汉字:
一个全角字符的GB码等于高位和低位的ASCII码(两个二进制数,正值)连接在一起的数值。
即GBcode = (unsigned char) char[0] * 256 + (unsigned char) char[1]
对照GB2312简体中文编码表,汉字的GB码大于0xB0A0,所以
if(GBcode > 0xB0A0)zhNum++;
判断是否有全角的特殊符号,就可以用GB码小于0xB0A0(或者对应GB2312表查找对应的范围)
源码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Max 2048 //Assuming that the text is a maximum of 2048 bytes
int main(){
int zhNum=0,figNum=0,spNum=0;//They are the number of Chinese characters, Numbers and Spaces.
char txt[Max];
printf("Please enter the text:\n");//Prompt the user to input the text
fgets(txt,Max,stdin);
for(int i=0;i<strlen(txt);i++){
if(txt[i]<0&&txt[i+1]<0){
int GBK=(unsigned char)txt[i]*256+(unsigned char)txt[i];
if(GBK>0xB0A0)
zhNum++;
i++;//Because the full Angle character takes up two bytes, it goes straight to the next byte's next byte judgment
}
else if(txt[i]>='0'&&txt[i]<='9')figNum++;
else if(txt[i]==' ')spNum++;
}
printf("Chinese characters' number is %d.\nThe number of figure is %d.\nThe number of spaces is %d.\n",zhNum,figNum,spNum);
return 0;
}