编译环境为: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; }
这个解释到这里,看表面以上的字,我明白了,
但更深一层就是没有看懂。
求解。!!~~~