C K&;R手册1.5.1文件复制

C K&;R手册1.5.1文件复制,c,getchar,putchar,C,Getchar,Putchar,关于这个K&R的例子,我在网站上到处看看,答案似乎围绕着“为什么这是int型还是EOF型?”这类人。我相信我理解这些。 这是我不理解的结果。我原以为这段代码只需要一个字符,打印出来,然后等待另一个字符或EOF 我看到的结果是输入等待,直到我按return,然后我键入的所有内容都显示出来,更多的内容等待输入 while循环是否只是“循环”,直到我用carrage返回结束文本流,然后显示putchar(c)在某处隐藏了什么 代码是: #include <stdio.h> /* copy

关于这个K&R的例子,我在网站上到处看看,答案似乎围绕着“为什么这是int型还是EOF型?”这类人。我相信我理解这些。 这是我不理解的结果。我原以为这段代码只需要一个字符,打印出来,然后等待另一个字符或EOF

我看到的结果是输入等待,直到我按return,然后我键入的所有内容都显示出来,更多的内容等待输入

while循环是否只是“循环”,直到我用carrage返回结束文本流,然后显示putchar(c)在某处隐藏了什么

代码是:

#include <stdio.h>

/* copy input to output: 1st version */
main()
{
    int c;

    c = getchar();
    while(c != EOF) {
        putchar(c);
        c = getchar();
    }  
}
#包括
/*将输入复制到输出:第1版*/
main()
{
INTC;
c=getchar();
而(c!=EOF){
普查尔(c);
c=getchar();
}  
}
现在,如果我在这段时间之前在线路上偷偷地使用一个putchar(c),我会得到我所期望的。我仍然必须输入文本流并按return。结果是流的第一个字符,程序退出

显然,对我来说,这是一个很大的差距


感谢您的帮助

默认情况下,stdin和stdout是缓冲的。这意味着他们会保存成批的字符,并立即发送以提高效率。通常,在缓冲区中没有更多空间或流中有换行符或EOF之前,会保存批处理

当您调用
getchar()
时,您的请求来自stdin中的字符。假设您键入
A
,该字符将保存在缓冲区中,然后系统将等待更多输入。如果键入
B
,该字符将进入下一个缓冲区。也许在那之后,你点击回车键,一个换行符被放入缓冲区。但是换行符也会中断缓冲过程,因此对
getchar()
的原始调用将返回缓冲区中的第一个字符(
A
)。在下一次迭代中,再次调用
getchar()
,它会立即返回缓冲区中的下一个字符(
B
)。等等

因此,并不是while循环一直运行到行尾,而是对
getchar()
(当缓冲区为空时)的第一个调用正在等待,直到缓冲区已满或看到换行

当您交错输出函数时,如
putchar()
,大多数C运行时库在您向stdout发送数据时会“刷新”stdin(反之亦然)。(目的是确保用户在程序等待输入之前看到提示。)这就是为什么在添加
putchar()
调用时开始看到不同的行为

您可以使用
flush()
函数手动刷新缓冲区。您还可以使用
setvbuf()
控制标准流使用的缓冲区大小

正如Han Passant在评论中指出的,换行符不会“终止流”。要在stdin上获得EOF,必须键入Ctrl+D(或者在某些系统上键入Ctrl+Z)。EOF还将刷新缓冲区。如果您已将另一个程序的文件或输出重定向到stdin,则一旦输入用尽,将发生EOF


虽然K和R C很旧,甚至ANSI C也不像现在那么普通,但是在当前的标准中,甚至在C++中,用STDIN和STDUT缓冲的所有东西都是有效的。我认为唯一有意义的变化是C标准现在明确提出了让stdin和stdout导致另一个刷新的可取性。

我感谢您的回答,您描述的缓冲非常有用和有趣

显然,我也必须有错误的阅读/理解,K&R。他们将文本流定义为“…由零个或多个字符组成,后跟一个新行字符”,我认为这意味着返回/回车键;结束它,然后允许输出

此外,我还要感谢所有提出了有益意见的人


顺便说一句,我清楚地知道我必须输入^D来生成EOF,这将终止程序。我感谢你们都是顶级程序员,感谢你们抽出时间。我想我需要找另一个地方来讨论R&R写的关于这个练习的文章是关于什么的

不要使用K&R编码样式,它已被弃用。C在过去的17年中已经进化。关于你的文本:不确定你的具体问题是什么。这不是一个教程网站。这是因为标准的输入和输出是缓冲的:输入的字符存储在内部,直到你点击回车键,然后批量处理。同样,输出字符将一直存储到打印新行字符为止,此时所有内容都将刷新。如果您想在输入和输出之间建立直接的对应关系,则必须使用特殊的库而不是控制台I/O。而且
CR
(也称为回车符)不会终止流。@Olaf第一个版本教导旧的、标准之前的C,这是正确的。这应该避免。第二个版本教授ANSI-C,这仍然非常相关。大量的C仍然是用ANSI-C编写的。这可能会有所帮助。