首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

getchar、putchar和getc、puts的有关问题

2014-01-03 
getchar、putchar和getc、puts的问题。#include stdio.hint main(){char cwhile((c getchar()) ! EOF)p

getchar、putchar和getc、puts的问题。
#include <stdio.h>

int main()
{
char c;

while((c = getchar()) != EOF)
putchar(c);
return 0;
}

运行结果
getchar、putchar和getc、puts的有关问题

int main()
{
char foor[20];

while(gets(foor) != NULL)
puts(foor);
return 0;
}
运行结果
getchar、putchar和getc、puts的有关问题
以上两个程序,均是死循环。运行效果完全相同。?

[解决办法]
均是死循环?

不是的,getchar和gets都有返回NULL的时候,这时while的条件就不满足了,循环就结束了;
那它们什么时候返回NULL呢?当它们读到EOF的时候;
那控制台怎么输入EOF呢?Windows下就是Ctrl+Z

运行效果完全相同?

也不是的,看上去一样,实际运行的原理还是不一样的。
getchar每次读入一个字符,gets每次读一行(但会丢弃回车),这就是它们的区别;
为什么都是回车之后才有反应?因为标准IO都是有缓冲的,而且是行缓冲,
这意味着“标准输入流”只有在按回车之后,输入的东西才会进入流(输入的东西也包括了回车)
比如,刚进入程序,“标准输入流”中没有任何东西,这时getX会等待输入(还没有进循环体)
用户输入abc,“标准输入流”还是没有东西,直到用户输入回车<cr>,这时“标注输入流”中才有东西:
abc<cr>
这时标准输入流有东西了,getX可以返回了,

getchar从stdin中读入一个字符a,返回该字符,该字符不为NULL,进入循环体,putchar该字符;然后又回到while,读入下一个字符b,不为NULL,putchar该字符,一直到<cr>,getchar读入<cr>,不为NULL,putchar <cr>产生回车效果,这时stdin空了,等待用户的下一次输入

而gets从stdin中读入abc<cr>,并将abc存入foor(<cr>丢弃),由于成功读入,gets返回foor,它并不是NULL,从而导致进入循环体,puts将输出foor,即abc,同时puts会多输出个回车,然后又回到while,这时stdin已空,程序停下来等待用户的下一次输入

由此可以发现,用户输入
abc<cr>
getchar while了四次,而gets只while了一次,这就是它们区别的表现,单纯看输入输出是看不出来的,可以通过debugger跟踪程序的运行,来理解while的过程;也可以通过加一个循环counter,来跟踪while的次数。

核心概念:流
[解决办法]

引用:
Quote: 引用:

Quote: 引用:

我运行了一遍,感觉是一样的啊,空格和回车都是一样的

不是一不一样的问题。
是逻辑问题
第一个程序:
你希望输入一个字符,输出一个字符,才会写成第一个程序那种形式
实际上,是你输入一行,它输出一行,和你的预期完全不符。
这是一种设计错误。
第二个程序
设计的就是输入一整行,接着输出一整行。
结果完全符合要求。


不知道为什么putchar能输出字符串,明明用的getchar和putchar却能输出和获得字符串

因为是缓冲IO 或者叫 流IO
不论输入输出,都是先放在缓冲里的
只有遇到回车,才开始真的读取,和输出

这里有两个输入输出过程
1)输入
1.1) 1个是用户敲键盘,输入数据到输入流缓冲

1.2) 1个是程序中 getchar() 这个函数,从输入缓冲读取字符 并赋值给c

流输入并不是用户输入一个,getchar()就会执行一次
而是getchar()函数,一直在等待,直到输入流被更新;
即用户输入回车的时候,才开始读取流缓冲中的数据;
而只要流缓冲有数据,getchar()就可以不用等待,一直读取,直到流缓冲被读空。
2)输出

2.1) 1个是 putchar()函数直接把 c 输出到流缓冲;

2.2) 1个是,流缓冲等待输出回车换行,才开始清理流缓冲;
一次性,把一行数据,输出到 stdout 对应的文件或设备中(屏幕)。
此时,输出流缓冲被清空,后面就可以重新输出数据到流缓冲了。


那么,现在看看第一个程序的输入输出过程
程序中
while((c = getchar())!=EOF)
{
    putchar(c);
}


每次调用getchar,把一个字符读到c中,如果缓冲没有数据,
那么就一直等待用户输入,直到用户输入回车('\n');
此时getchar返回输入流缓冲中,接收的第一个字符;

输入流缓冲,此时,接收一行字符,包括回车换行(‘\n’)。
getchar返回后,只有第一个字符赋值给了c 其他字符还在输入流缓冲。

此时程序调用putchar函数输出c

只要这个字符不是‘\n’ ,那么这个字符只是输出到流缓冲,并不输出到屏幕。
接着又是调用getchar, 然后 putchar

当 getchar读到‘\n’时,接着putchar 输出‘\n’
此时用户输入的一整行数据,才开始输出到屏幕

结果就是输入一行,输出一行
然后,再重新开始这个过程。

直到读到文件结束标志,此时c == EOF,就是键盘输入ctrl Z ,显示 ^Z,结束程序的运行。
linux ,unix 键盘输入ctrl D ,显示 ^D

 

热点排行