我使用getchar()
和puchar()
和'\n'
和EOF(在Visual Studio中)测试了很多情况,以更好地了解缓冲和getchar
的工作原理。
如果我的代码
int c;
printf("Enter character\n");
/* 1 - number for explaining steps */
c = getchar();
putchar(c);
/* 2 */
c = getchar();
putchar(c);
printf("hi");
在此代码中,如果我输入字符 a
并按 Enter 键,它将显示
a
hi
这意味着当我按下时'\n'
也会保存在缓冲区中,然后缓冲区中的第一项(a
)转到第一个c=getchar()
并打印a
;然后缓冲区中的第二项(\n
)转到第二个c=getchar()
并打印新行。
我得出结论,'\n'
保存在缓冲区中,这不是命令在按回车键时能够转到新行的结果,因为我为此测试了另一个代码:
while ((c = getchar()) != '\n')
putchar(c);
printf("hi");
在这段代码中,当我键入< code>a并按enter键时,它会打印< code>ahi,而新行不会打印,这意味着当< code>a传递给< code>getchar()时,< code>putchar()会打印它,然后当< code>getchar()获取< code>'\n'时,循环终止,循环内的< code>putchar()不会打印新行,因此该命令不会
现在我想测试另一个代码:
int c;
while ((c = getchar()) != EOF)
putchar(c);
printf("hi");
return 0;
在这个中,如果我传递它abc
和EOF的信号(在我的系统中^Z(Ctrl Z)),它将显示abc-
但是,相反,它打印-
第一个示例中输入如何首先读取<code>a</code>,然后读取换行符的概述基本正确。就getchar()
而言,换行符是一个完全正常的字符;事实上,没有异常字符getchar()
可以返回任何符合char
的8位值,外加一个额外的值,称为EOF。这就是为什么它的返回值必须存储在<code>int</code>中的原因。
当底层read()
系统调用返回0个可读取字节时,或者当出现错误时,标准I/O函数返回EOF。
当您在Windows上键入abc
Control-Z时(您将在Unix上键入Control-D),然后:
abc
) 中的当前字符可用于 read()
系统调用。read()
系统调用使用这些字符填充标准 I/O 缓冲区。getchar()
调用返回 a
、b
和 c
。getchar()
等待更多输入。这不是EOF;它只是将线路上的字符冲洗到程序中。要获得 EOF 的效果,您必须在 abc
之后连续键入 Control-Z 两次。第一个会冲洗 abc
;第二个将生成 0 字节的 read(),
指示 EOF。
当按下换行符(Enter)时,终端驱动程序也会提供输入。如果在键入Enter后立即键入Control-Z,则所有零个待输入字符将从终端发送到程序,因此read()
返回0,因此标准I/O包报告EOF。
请注意,在按回车键或EOF指示之前,您可以使用退格键和其他编辑选项编辑行中的数据,包括删除所有数据。一旦你点击回车或EOF指示,你就不能再编辑可供read()
使用的数据。
类似的行为发生在Unix上;键入两次EOF指示以终止输入中线;一次以在行的开始处终止输入。
关于堆栈溢出有许多相关问题,包括以下问题:
同时((c=getc(file)) ! = EOF)
循环不会停止执行而(getchar() ! = EOF)
循环read()
from stdin不会忽略换行符