(HPU算法协会新生训练题(二)C-C)
这是我自己写的解决方法, 拙作请见谅
题目
统计给定文本文件中汉字的个数。
输入
输入文件首先包含一个整数n,表示测试实例的个数,然后是n段文本。
输出
对于每一段文本,输出其中的汉字的个数,每个测试实例的输出占一行。
[Hint:]从汉字机内码的特点考虑~
先来看代码吧
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
int n;
char zfc[1000];
int length;
int number=0;
while (~scanf("%d",&n))
{
while (getchar()==0)
{
break;
}//清空输入流,否则下面的gets会接收到提交数字而按下的回车键
for (int i = 0; i < n; i++)
{
gets(zfc);//用scanf不适用空格键
length=strlen(zfc);
for(int e=0;e<length;e++){
if(zfc[e]<0){
//汉字的ASCII码值是负的
number++;
}
}//遍历字符串
printf("%d\n",number/2);//汉字为两个字节,所以除以2
number=0;//格式化
}
}
return 0;
}
第一点
现在我们来分析一下
以scanf()的返回值并且加上~符号来转义,以此来作为while的判断条件,在其他的题目中经常遇到要求输入0使程序退出且没有输出,如果想实现这个功能可以使用下面的代码
int n;
while (~scanf("%d",n),n)
{
//code
}
如下同理
int n=(1,2);
printf("%d",n);
若将变量以如(a,b)赋值,则变量的值为后者
第二点
while (getchar()==0)
{
break;
}
C primer plus 第6版中有详细用法和介绍。
当用后输入完while中的scanf的值后,按下enter键提交,但是这个enter键同样也会加载到输入队列中,当下面的代码使用gets或者getchar进行输入时,缓冲区的内容被传到gets或getchar中,造成错误。
我来介绍几种解决方法
1.用以上方法将缓冲区的无用值释放掉,但是上面代码只能释放一个,可以使用循环来释放。
2.先看看c语言的api文档
setbuf()函数设置stream(流)使用buffer(缓冲区),如果buffer(缓冲区)是null,关闭缓冲. 如果使用非标准缓冲尺寸, 它应该由BUFSIZ字符决定长度.
setbuf(stdin, NULL);//使stdin输入流由默认缓冲区转为无缓冲区
**
3.第一种方法的进阶版
while ((c = getchar()) != EOF && c != '\n');//不停地使用getchar()获取缓冲中字符,直到获取的c是“\n”或文件结尾符EOF为止
4.不太建议的方法
注意:有很多人可能觉得使用fflush(stdin);不就能清空缓冲区了,但使用这种方法有很多不确定性。
网上查了原因:C和C++的标准里从来没有定义过 fflush(stdin)。
某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,
但是并非所有编译器都要支持这个功能(linux 下的 gcc 就不支持),//亲测确实如此在linux的gcc下不能清空缓冲区
因为标准中根本没有定义 fflush(stdin)。
MSDN 文档里 也清楚地写着
fflush on input stream is an extension to the C standard(fflush 操作输入流是对 C 标准的扩充)。
当然,如果你毫不在乎程序的移植性,用 fflush(stdin) 也没什么大问题。
所以大家最好不要使用fflush,移植性不好,反正上面的方法也不烦。
详细文档
第三点
**关于汉字的ASCII码,在大学计算机书中有一部分介绍汉字机内码,从网上找了一些详细易懂的解释就是汉字的ASCII码是负值这样可以来判断是否为汉字,同样还有一点需要注意,一个汉字占两个字节,故计算汉字的个数时需要除以2。
就那么多了,要点都差不多讲完了。嘻嘻!