对getchar()及putchar()的纠结

编译环境为:MinGW,

系统环境:winXP

 

代码来源《The C Programming Language (Second Edition)》:

1 while((c =getchar())!=EOF){
2     putchar(c);
3 } 


此代码在上述所说的书的第一章。

代码中用到两个函数,getchar()和putchar()。

 

我对这两个函数刚开始很不了解,

1、getchar()的用法是怎么样的,

2、如何读取用户所输入的信息,

3、为什么每次输入数据回车后就会执行putchar()

4、为什么每次打印出自己输入的一行信息后不会跳出循环体

 

以上问题,有一部分有了一点的头绪:

 

1、getchar()获取用户输入数据,功能了解一点,但此问题还是没有头绪。

········???

 

2、如何读取用户输入数据,  等待数据输入直到回车后再打印输入的信息,

这是代码实现看到的,

但是,具体 的实现不了解,待添加。。

........???

 

3、代码实现看到的,一行后自动打印此行,

EOF=='\n',这个为真??

 

4、代码实现过程中,我只有按“Ctrl + c”才可以强制关闭。

代码中循环体中的中止条件是:getchar() != EOF

在此时,循环体是如何中止的??

在输入数据后打印信息,这时有没有中止的语句让其打印信息??

而打印数据后,又在等待用户输入数据。此时,又是如何让其停止打印的??

 

 

 2012-06-22

以下是原书对上述代码的详解:

在该程序中,while循环语句首先读一个字符并将其赋值给c,然后测试该字符是否为文件结束标志。如果该字符不是文件结束标志,则执行while语句体,并打印该字符。随后重复执行while语句。当到达输入的结尾位置时,while循环语句终止执行,从而整个main函数执行结束。

 

在此之前所涉及到的4个问题总结一下。

这里涉及到运算符的优先级、getchar()的内部运行。

首先对while循环体的条件再次解剖:( ( c = getchar() ) != EOF )

根据原文解说getchar()函数是边输入边赋值,

但是我看到一篇文章说getchar()说:

getchar()有一个int型的返回值.当程序调用getchar时,程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符.getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕.如用户在按回车之前输入了一止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取.也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键.

这么说,( c = getchar() ),最后c的值应该是用户输入的第一个字符的ASCII码,

那么,当我输入:

abc

不回车再按“Ctrl + C”,结果是不会输出“abc”,而是直接退出while循环。

这时,我又纠结了。。。

 

 

 

 

2012-06-23

继续前文!

对于前文所说的,getchar()返回值为用户输入的第一个字符的ASCII码,

那么c的值应该为一个字符的ASCII码,

执行:

putchar(c); 这条语句时,为什么不是只是输入一个字符,而是把输入的字符都打印出来。(字符中不包括“Ctrl + z”的值)

。。。

 

 

 

 

 

2012-07-02

找到对getchar()的解释。

 

以下宏定义是在csdn论坛上摘:

#define getchar() getc(stdin)

#define getc(_stream) ( --(_stream)->_cnt >= 0 ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream) )

 

以及它的解释:

“getchar()

它的作用是从stdin流中读入一个字符,也就是是,如果stdin有数据的话不用输入它就可以直接读取了,第一次getchar()时,确实需要人工的输入,但是如果你输入了多个字符,以后的getchar()再执行时就会直接从缓冲区中读取了。

实际上是:输入设备 -> 内存缓冲区 -> 程序getchar

你按的键是放进缓冲区了,然后供程序getchar

你有没有度过按住很多键然后等一会儿会滴滴滴滴响,就是缓冲区满了,你的后头按的键没有存进缓冲区。

键盘输入的字符都存到缓冲区内,一旦键入回车,getchar就进入缓冲区读取字符,一次只返回第一个字符作为getchar函数的值,如果有循环或足够多的getchar语句,就会依次读出缓冲区内的所有字符直到'\n'。

要理解这一点,之所以你输入的一系列字符被依次读出来,就是因为循环的作用使得反复利用getchar在缓冲区里读取字符,而不是getchar可以读取多个字符。

事实上getchar每次只能读取一个字符。

 

简化以上引用的信息,也引用csdn论坛中的一句话:

“首先getchar()是个宏,而不是函数,它涉及到IO基本输入输出流。

 

现在的问题还剩下:

顶头的代码,

while循环的条件是输入字符不等于EOF,

可是输入任意字符串“khkseud”紧接着“Ctrl +z”回车,后再“Ctrl + z”回车,

这样的操作才退出循环!

问:为什么第一个“Ctrl + z”不起退出循环的作用?

 

 

 

 

2012-07-03

今天,针对上一个问题得到了解释。

这是系统调用跟踪,来自CSDN论坛:

uname({sys="Linux", node="localhost.localdomain", ...}) = 0
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb774c000
read(0, 1234"1234", 1024)                   = 4
read(0, "", 1024)                       = 0
exit_group(0)                           = ?

并引用提供该解释的内容:

“这是系统调用跟踪,可以看到输入1234ctrl+d后,系统完全没有意识到ctrl+d的

(也就是ctrl+d和没按过是一样的)存在阻塞在倒数第二行,再次输入ctrl+d后才read return 0。

这不是c库的实现问题,也不是系统API的问题,只能说是shell的问题了,因为如下也是同样的系统调用流程:


 

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

int main(int argc, char* const argv[]) {
        char buffer[100];
        while (read(0, buffer, 100) > 0) {

        }
        return 0;
}

 

这个解释到这里,看表面以上的字,我明白了,

但更深一层就是没有看懂。

 

求解。!!~~~


 

 

 

转载于:https://www.cnblogs.com/feminping/archive/2012/06/20/c_getchar_putchar_how_to_use.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值