我发现getchar()
在某些情况下表现不同。
在下面的代码中,它吞噬了输入中的换行符。
#include <stdio.h>
// copy input to output; 1st version
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
}
}
终端中的输入和输出如下所示。
j
j
b
b
asdf
asdf
ashdfn
ashdfn
它完全复制输入并忽略输入中的换行符,因为我在每次输入后按下了返回键。
但是,如果循环内有printf()
语句,它将不再忽略换行符。
#include <stdio.h>
// copy input to output; 1st version
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
printf("\n");
}
}
终端中的输入和输出如下所示。
j
j
b
b
asdf
a
s
d
f
ashdfn
a
s
h
d
f
n
它与换行符相呼应,这在以前的情况下被忽略。
你能告诉我为什么有差异,它是如何准确表现的吗?
在第一种情况下,它读取一个字符-getchar()
并打印它-putchar()
,因此每个字符后没有换行符或'\n'
。换行符是您使用回车键输入的那个。
而在第二种情况下,您有printf("\n")
,它在打印每个字符后打印新行-通过putchar()
。
getchar
一次读取一个字符。当您输入123
并按Enter键时,此输入将进入C标准缓冲区,其中还有一个字符\n
(在按Enter键时生成)。现在从那里getchar
一次读取一个字符,输入流中的其余字符将留给getchar
的下一次调用。现在,为了回答您的问题,我将用一个简单的程序来解释它;
#include <stdio.h>
int main(void)
{
int c, b;
c = getchar();
putchar(c);
b = getchar();
putchar(b);
b = getchar();
putchar(b);
}
给出输入123
,缓冲区的输入流将是
123\n
有四个char
s;'1'
、'2'
、'3'
和'\n'
。
首先getchar
读取1
,然后putchar
输出这个字符。现在缓冲区有23\n
。getchar
的下一次调用读取2
,旁边将读取3
。最后\n
被留下用于getchar
的下一次调用。因此输出将是
123
现在像第一个例子一样一个接一个地输入字符。在传递j
时,您将j\n
传递到缓冲区。getchar
的第一次调用将读取j
并在屏幕上输出putchar
。下一次调用将读取\n
并且putchar
在屏幕上打印出来,但直到读取下一个字符时才会看到效果。在getchar
的第三次调用中,b
被读取,但这次它会转到输出屏幕上的下一行。这是因为getchar
之前读取的\n
字符。最后\n
被留在缓冲区中,用于getchar
的下一次调用。
现在来看你的第一个例子
#include <stdio.h>
// copy input to output; 1st version
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
}
}
这将类似于上述工作。
现在来看第二个例子
#include <stdio.h>
// copy input to output; 1st version
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
printf("\n");
}
}
这是在每个字符后打印两个换行符,但应该打印一个字符,对吗?
它正在打印它应该打印的东西!这是因为它不仅为字符j
、b
…等打印换行符,还为换行符\n
打印换行符。接受简单的输入j\n
,b\n
。
在getchar
的第一次调用时,j
被printf
读取并用换行符打印,然后在下一次调用\n
时与换行符一起打印,输出如下所示
j
//The newline printed by printf along with j
//The newline printed by printf along with \n
b
它不回显换行符。getchar()
是缓冲输入。此外,getchar()
是回显类型。控件将等到您从键盘按Enter
键。
如果你这样做
abcde
由于getchar()
是回显类型,它从缓冲区中读取单个char
,直到遇到换行符
并回显相同的char
。putchar()
在终端上打印接收到的char
。当您按Enter时,您将输入正在输出的换行符。
同样的事情发生在第二种情况下,但由于printf
而添加了一行。