(HPU算法协会新生训练题(二)C-C)

(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
就那么多了,要点都差不多讲完了。嘻嘻!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值