Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在getchar()获取EOF之前,似乎必须先按enter键_C_Windows_Eof - Fatal编程技术网

在getchar()获取EOF之前,似乎必须先按enter键

在getchar()获取EOF之前,似乎必须先按enter键,c,windows,eof,C,Windows,Eof,我开始学习EOF,并编写了以下简单程序: #include<stdio.h> #include<stdlib.h> #include<string.h> void main() { int i=0; while(getchar()!=EOF) { i++; } printf("number of characters : %d \n",i); } 问题

我开始学习EOF,并编写了以下简单程序:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>   

void main()
{    
    int i=0;
    while(getchar()!=EOF)
    {
        i++;    
    }       
    printf("number of characters : %d \n",i);       
}

问题是,当我写一个字符串时,按enter键,然后按Ctrl+Z,输出是我写的字符数加上EOF的1。但是,如果我写了一个字符串,并且在不更改行的情况下,按Ctrl+Z组合键,则循环不会终止。为什么会这样?

我在这里看到了与此相关的主题。您需要做的是将pts/tty设置为非cannonical模式,并立即使用某种TCSANOWdo attr更改来完成。
您可以使用termios.h中的函数在struct termios上进行操作

输入使用缓冲区。第一个getchar请求系统级读取。按enter键或ctrl-z键时,读取操作会将缓冲区返回给程序。按enter键时,系统还会在返回前向缓冲区添加换行符。Eof不是实际字符,而是读取空缓冲区的结果

控件返回到程序后,getchar顺序读取返回的缓冲区中的每个字符,完成后请求另一次读取

在第一种情况下,getchar读取包含换行符的缓冲区。然后,由于缓冲区为空,getchar请求另一个读取,该读取通过按ctrl-z中断,返回一个空缓冲区并导致EOF

在第二种情况下,按ctrl-z只会返回缓冲区,在getchar完成读取后,它会请求另一个未完成的读取,因为您再也不会按ctrl-z或enter键

永远不会结束的不是while循环,而是read调用。在第二种情况下,尝试按ctrl-z两次。

首先,只有在ctrl+z位于行首时,才会发出EOF信号。考虑到这一点:

第一次尝试输入10个字符,然后输入时,实际上是将输入\n推送到输入流,该流通过getchar逐字符读取,现在有11个字符,由于输入,在末尾添加了新行

在新行中,然后使用Ctrl+Z组合来向EOF发送信号,并且确实在那里正确地执行了该操作;向EOF发送信号,得到11作为结果

奇怪的是,你竟然期望在这里看到10个。如果你要输入多行呢?您希望它不计入新线路吗?然后你可以使用类似的方法:

int onechar;
while ((onechar = getchar( )) != EOF)
{
    if (onechar != '\n')
        i++;
}
或者更进一步,您是否总是期望一行输入?然后,您可能需要考虑将循环条件更改为以下内容:

while(getchar( ) != '\n')
{
    i++;
}
oor,您希望它能够获得多行输入,并计算\n个字符,最重要的是,只希望它能够停止在不一定在行首的Ctrl+Z组合处吗?那么,这里有这个:

// 26 is the ASCII value of the Substitute character
for (int onechar = getchar( ); onechar != EOF && onechar != 26; onechar = getchar( ))
{
    i++;
}
26,正如所评论的,是,这是当我不适当地使用Ctrl+Z时程序得到的,至少在我的机器上是这样。使用此选项,如果要输入:

// loop terminated by the result of (onechar != 26) comparison
your input^Z
// loop terminated by the result of (onechar != EOF) comparison
your input
^Z
您将得到10作为结果,如果您要输入:

// loop terminated by the result of (onechar != 26) comparison
your input^Z
// loop terminated by the result of (onechar != EOF) comparison
your input
^Z

你会得到11,算上你输入的那一行和之前的10个字符。在这里,^Z用于显示Ctrl+Z组合键作为输入。

添加了窗口,因为我使用Ctrl+Z作为EOF,这是您的平台。顺便说一句,如果你关心可移植代码,main应该返回int,而不是void。@larsmans首先,我想我必须知道这是如何工作的,然后我会开始担心可移植代码。。!看到了吗?是的,paxdiablo说,如果我在之后按任意位置的Ctrl+Z和newline,我会完成我的工作,但我已经完成了,程序会继续,而不会停止。