getchar()
函数从屏幕读取一个字符并返回它的ASCII值。此函数一次只能读取单个字符。
putchar()
函数将传递的字符放在屏幕上并返回字符的ASCII值。此功能一次只能放置一个字符。
现在考虑下面的Code 1
#include<stdio.h>
void main()
{
int c=getchar();
putchar(c);
}
输出:
ABCD
一
现在考虑Code 2
:
#include<stdio.h>
void main()
{
int c=getchar();
while(c!=EOF)
{
putchar(c);
c=getchar();
}
}
输出:
一
一
ABCD
ABCD
^ Z
Code 1
工作正常,如果我们输入的字符超过1个,那么getchar()
函数将只读取第一个字符并返回其ASCII
值。但是如果Code 2
有循环,为什么整个字符串被打印而不是1个字符?
答案 0 :(得分:0)
代码段1读取(无符号)字符,打印并结束程序。
代码片段2读取(无符号)字符,如果它没有读取EOF
(通常为-1),则打印字符并读取另一个(无符号)字符,程序重新开始打印它。否则,如果已经阅读了EOF
,则程序结束。
答案 1 :(得分:0)
这被称为&#34;线路纪律&#34; &#34; ICANON&#34;
长话短说:
来自终端的输入由线路&#34;处理。 NOTHING会传递给您的程序,直到您点击&#34; Return&#34;。
这样可以在出错时编辑该行(擦除最后一个字符并改写它)。这是由内核在getchar之前处理的(通常实现为宏)可以看到它。
类似地,输出在libc中缓冲,并且仅在&#34;换行符&#34;时才实际发送到内核。 (&#39; \ n&#39;)char被看到(除非你明确flush())。注意这与上面不同,因为它由libc处理,而输入由内核处理。
如果您想要一次一个地处理输入字符,请在键入后立即处理您必须设置用于&#34; cbreak&#34;的特定终端的线路规则。这是许多终端处理库所做的事情(例如:ncurses)。
查看stty(1)的手册页进行讨论。
返回您的代码段:
发生了什么事情所有的字符都在内核中缓冲(并在第一行中正确回显),直到你点击&#34; CR&#34;。
在这一点上,整条线传递给你的程序,它快乐地循环吃着字符并吐回来。
当&#34; cr&#34;到达(libc实际上将它转换为&#34; LineFeed&#34;&#39; \ n&#39;)整行您一次构建一个char是吐回内核,因此吐到终端。
然后你按下&#34; CTRL-Z&#34;,它被内核解释为EOF,因此通过libc返回(另一个getchar()将失败并返回-1)。
如果你想要能够读取所有字符(包括Win上的Ctrl-Z,在Unix / Linux下将是CTRL-D),你需要将行规则设置为&#34; raw&#34; (一种非常先进的功能可能会锁定您的终端;)。
答案 2 :(得分:0)
在代码2中,当您输入字符串时,请说出"abcd"
并按回车键,输入的数据将进入标准输入流(stdin
) 1 。 getchar()
从stdin
读取一个字符,然后程序的执行到达while
循环。
在循环中,putchar
输出c
中存储的字符,即您输入的第一个字符a
。下一次调用getchar
不会等待进一步输入,因为它会看到stdin
2 中的字符。此getchar
会读取下一个字符b
,因为它不是EOF
,循环会继续。
此过程一直持续到getchar
读取EOF
字符(使用CTRL+Z
输入),最后程序结束。
1 :所有数据都包含您按下的回车键
2 :这也意味着getchar
在stdin
为空时等待您输入字符。