C语言 while((c=getchar())!=EOF)死循环解决办法

死循环代码例子如下

(代码目的为得到文本中的行数、词数、字符个数)

#include <stdio.h>
#include <windows.h>
int main(void)
{
	int c,nl,nw,nc,inword;
	nl=nw=nc=inword=0;
	while((c=getchar())!=EOF)
	{
		nc++;
		if(c=='\n') nl++;
		if(c==' '||c=='\t'||c=='\n')
			inword=0;
		else if(inword==0)
		{
			inword = 1;
			nw++;
		}

	}
	printf("nl=%d,nw=%d,nc=%d\n",nl,nw,nc);
	system("pause");

	return 0; 
}

首先打印EOF(我们得先知道EOF是个what ghost??)
代码如下:

#include <stdio.h>
int main(void)
{
	printf("%d",EOF);

	return 0; 
}

输出结果为-1
我们发现这个没办法通过键入哪个键来表示的,因为ASCII码没有对应-1的键


所以到底怎么解决呢??

在windows中,常用ctrl+z来标识流的结束(据说专业的叫法是阻塞式检查ctrl+Z

注意:Ctrl+Z产生的不是一个普通的ASCII码值,也就是说它产生的不是一个字符,所以不会跟其它从键盘上输入的字符一样能够存放在输入缓冲区

从键盘上输入:一段文字+^z + 回车 之后,在Windows系统上是这样处理的:由于回车的作用,前面的文段被送到输入缓冲区(注意:^z不会产生字符,所以更不会存储到输入缓冲区,缓冲区中没有 ^z 的存在)。这时,getchar() 检测到输入缓冲区中已经有数据存在(因此不再检查是否有^z 的输入),于是从缓冲中读取相应的数据。如果都读取完了,则输入缓冲区重新变为空,getchar() 等待新的输入。可见,尽管有 ^z 按下,但是由于在此之前还有其它的字符(也就是说,不算是新起的一行),所以流也不会结束。
因此,输入流结束的条件就是:^z 之前不能有任何字符输入(回车除外) 换句话说,就是要回车(新起一行,打入ctrl+Z)(回显为^Z,否则 ^z 起不到流结束的作用。


网上收集知识点拓展(忘记从哪里找到的资料了)

关于Ctrl+Z、Ctrl+D

  • Windows系统中一般采用阻塞式检查 Ctrl+Z、Unix/Linux系统下一般采用非阻塞式的检查 Ctrl+D。因为是在Windows系统下,因此使用阻塞式的 Ctrl+Z 来标识流的结束。
    阻塞式检查方式指的是只有在回车键按下之后才对此前是否有 Ctrl+Z 组合键按下进行检查,非阻塞式样指的是按下Ctrl+D
    之后立即响应的方式。如果在按 Ctrl+D 之前已经从键盘输入了字符,则 Ctrl+D的作用就相当于回车,即把这些字符送到输入缓冲区供读取使用,此时Ctrl+D不再起流结束符的作用。如果按Ctrl+D
    之前没有任何键盘输入,则 Ctrl+D 就是流结束的信号。

猜你喜欢

转载自blog.csdn.net/weixin_43093006/article/details/83067256
今日推荐