c语言中getchar的用法的getchar使用问题

getchar() 疑惑_C++,C语言_ThinkSAAS
getchar() 疑惑
getchar() 疑惑
内容来源: 网络
因为最近正看从新看THE C
PROGRAMMING LANGUAGE 对getchar() 产生了疑惑,关于getchar()工作原理不了解,
1. #include &stdio.h&
2. main(){
while ((c=getchar())!=EOF)
putchar(c);
应该一次输入一个字符并显示,但是实际工作却不是,下面是查询的资料,感谢原创作者。
看到CU上一个人发的帖子,我回答错误了,在网上找了些资料后对getchar()又有了一些新的了解。
getchar():
我们用getchar()在控制台上取字符的时候,它首先要把所有取得的东西按照顺序放在内存的某个临时的地方,但我们输入回车时它会从这个地方开始在取字符,并按相同的顺序取,当取到回车时就是上次输入的最后一个字符,注意我们在一个程序里不论用多少getchar(),它都会存放在同一个地方,并且不断的向后增加,然后在用getchar()取的时候会从上次取的后面继续取,只要这个存储的地方有字符,那么我们用getchar()时控制台就不会停顿等待我们输入字符,只有当取到换行时才是表示这个地方完全空了,下次在用getchar()的时候控制台才会停顿等待用户输入字符!
while((c = getchar()) != EOF)3
原因在于程序中的变量c被声明为char类型,而不是int类型。这意味着c无法容下所有可能的字符,特别是,可能无法容下EOF。因此,最终结果存在两种情况。一种可能是:某些合法的输入字符在被“截断”后使得c的取值与EOF相同;另一种可能是,c根本不可能取到EOF这个值。对于前一种情况,程序将在文件复制的中途终止;对于后一种情况,程序陷入一个死循环。实际上,还有可能存在第三种情况:程序表面上似乎能够正常工作,但完全是因为巧合。尽管函数getchar的返回结果在赋给char类型的变量c时会发生“截断”操作,尽管while语句中比较运算的操作数不是函数getchar的返回值,而是“被截断”的值c,然而令人吃惊的是许多编译器对上述表达式的实现并不正确。这些编译器确实对函数getchar的返回值作了“截断”处理,并把低端字节部分赋给了变量c。但是,它们在比较表达式中并不是比较c与EOF,而是比较getchar函数的返回值与EOF!编译器如果采取的是这种做法,上面的例子程序看上去就能够“正常”运行了。
一、getchar的两点总结:1.getchar是以行为单位进行存取的。当用getchar进行输入时,如果输入的第一个字符为有效字符(即输入是文件结束符EOF,Windows下为组合键Ctrl+Z,Unix/Linux下为组合键Ctrl+D),那么只有当最后一个输入字符为换行符&
&(也可以是文件结束符EOF,EOF将在后面讨论)时,getchar才会停止执行,整个程序将会往下执行。譬如下面程序段:
while((c = getchar()) != EOF){
putchar(c);}
执行程序,输入:abc,然后回车。则程序就会去执行puchar(c),然后输出abc,这个地方不要忘了,系统输出的还有一个回车。然后可以继续输入,再次遇到换行符的时候,程序又会把那一行的输入的字符输出在终端上。
对于getchar,肯定很多初学的朋友会问,getchar不是以字符为单位读取的吗?那么,既然我输入了第一个字符a,肯定满足while循环(c = getchar()) != EOF的条件阿,那么应该执行putchar(c)在终端输出一个字符a。不错,我在用getchar的时候也是一直这么想的,但是程序就偏偏不着样执行,而是必需读到一个换行符或者文件结束符EOF才进行一次输出。
对这个问题的一个解释是,在大师编写C的时候,当时并没有所谓终端输入的概念,所有的输入实际上都是按照文件进行读取的,文件中一般都是以行为单位的。因此,只有遇到换行符,那么程序会认为输入结束,然后采取执行程序的其他部分。同时,输入是按照文件的方式存取的,那么要结束一个文件的输入就需用到EOF(Enf Of File). 这也就是为什么getchar结束输入退出时要用EOF的原因。
2.getchar()的返回值一般情况下是字符,但也可能是负值,即返回EOF。
这里要强调的一点就是,getchar函数通常返回终端所输入的字符,这些字符系统中对应的ASCII值都是非负的。因此,很多时候,我们会写这样的两行代码:
char c;c = getchar();
这样就很有可能出现问题。因为getchar函数除了返回终端输入的字符外,在遇到Ctrl+D(Linux下)即文件结束符EOF时,getchar()的返回EOF,这个EOF在函数库里一般定义为-1。因此,在这种情况下,getchar函数返回一个负值,把一个负值赋给一个char型的变量是不正确的。为了能够让所定义的变量能够包含getchar函数返回的所有可能的值,正确的定义方法如下(K&R C中特别提到了这个问题):
int c;c = getchar();
二、EOF的两点总结(主要指普通终端中的EOF)1.EOF作为文件结束符时的情况:
EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符。(1)遇到getcahr函数执行时,要输入第一个字符时就直接输入Ctrl+D,就可以跳出getchar(),去执行程序的其他部分;(2)在前面输入的字符为换行符时,接着输入Ctrl+D;(3)在前面有字符输入且不为换行符时,要连着输入两次Ctrl+D,这时第二次输入的Ctrl+D起到文件结束符的功能,至于第一次的Ctrl+D的作用将在下面介绍。其实,这三种情况都可以总结为只有在getchar()提示新的一次输入时,直接输入Ctrl+D才相当于文件结束符。
2.EOF作为行结束符时的情况,这时候输入Ctrl+D并不能结束getchar(),而只能引发getchar()提示下一轮的输入。
这种情况主要是在进行getchar()新的一行输入时,当输入了若干字符(不能包含换行符)之后,直接输入Ctrl+D,此时的Ctrl+D并不是文件结束符,而只是相当于换行符的功能,即结束当前的输入。以上面的代码段为例,如果执行时输入abc,然后Ctrl+D,程序输出结果为:
abcabc
注意:第一组abc为从终端输入的,然后输入Ctrl+D,就输出第二组abc,同时光标停在第二组字符的c后面,然后可以进行新一次的输入。这时如果再次输入Ctrl+D,则起到了文件结束符的作用,结束getchar()。如果输入abc之后,然后回车,输入换行符的话,则终端显示为:
//第一行,带回车abc
//第三行
其中第一行为终端输入,第二行为终端输出,光标停在了第三行处,等待新一次的终端输入。从这里也可以看出Ctrl+D和换行符分别作为行结束符时,输出的不同结果。EOF的作用也可以总结为:当终端有字符输入时,Ctrl+D产生的EOF相当于结束本行的输入,将引起getchar()新一轮的输入;当终端没有字符输入或者可以说当getchar()读取新的一次输入时,输入Ctrl+D,此时产生的EOF相当于文件结束符,程序将结束getchar()的执行。【补充】本文第二部分中关于EOF的总结部分,适用于终端驱动处于一次一行的模式下。也就是虽然getchar()和putchar()确实是按照每次一个字符
进行的。但是终端驱动处于一次一行的模式,它的输入只有到“
”或者EOF时才结束,因此,终端上得到的输出也都是按行的。如果要实现终端在读一个字符就结束输入的话,下面的程序是一种实现的方法(参考《C专家编程》,略有改动)
/*Edit by Godbach
CU Blog: */#include &stdio.h&#include &stdlib.h&
int main(void){
/* 终端驱动处于普通的一次一行模式 */
system("stty raw");
/* 现在的终端驱动处于一次一个字符模式 */
c = getchar();
putchar();
/* 终端驱动处又回到一次一行模式 */
system("stty cooked");
return 0;}
编译运行该程序,则当如入一个字符时,直接出处一个字符,然后程序结束。由此可见,由于终端驱动的模式不同,造成了getchar()输入结束的条件不一样。普通模式下需要回车或者EOF,而在一次一个字符的模式下,则输入一个字符之后就结束了。
mian() {c=getchar();putchar(c);}以上程序能输出第一个字符比如输入asd输出a#include&stdio.h&main(){ while((c = getchar()) != 0) putchar(c);}这个是ABD ABD getchar是从缓存中读数据,也就是说,你输入a,程序并不反映,只是把a存到缓存中,直到你输入结束,输了回车,程序才反映。
//--------------------- 第一个程序,键盘输入asd回车,getchar()函数读第一个字符,a,赋值给c,然后putchar(c)把结果输出,a。第二个程序,输入asd回车,getchar()读第一个字符a,赋值给c, c的值是a,(c=getchar())此时的值就是a,然后while进行判断,当然这个值不是0,即while的条件为真,执行putchar(c)输出a由于while条件为真,循环继续,再读一个,就读了s,与上面描述一样,while条件依然是真,执行putchar输出s第三次输出d这时条件依然是真,再读一下,由于输入了回车,getchar读到没值了,c=0,结束循环
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信  getchar()在C程序中的功能是接收一个字符,当我们在连续输入字符的时候getchar()会给你意想不到的效果。下面是net小伙做的一些测试:
首先看下面的这个程序:
1 #include&stdio.h&
2 #include&stdlib.h&
3 int main(void)
int a,b,c;
printf("please input num a:\n");
scanf("%d",&a);
printf("please input num b:\n");
scanf("%d",&b);
printf("please input num c:\n");
scanf("%d",&c);
printf("%d,%d,%d",a,b,c);
运行结果可想而知:
那么把int改成char之后会是神马结果呢?来看下一段代码:
1 #include&stdio.h&
2 #include&stdlib.h&
3 int main(void)
char a,b,c;
printf("please input num a:\n");
scanf("%c",&a);
printf("please input num b:\n");
scanf("%c",&b);
printf("please input num c:\n");
scanf("%c",&c);
printf("%c,%c,%c",a,b,c);
你能猜到运行结果是什么吗?
为什么会显示这样的结果?你猜到是什么原因了吗?
我们再来看一下源代码:程序连续接收了三个字符,在C中enter键代表一个换行符,所以当输入完a的值&q&之后按下enter键,换行符立马被字符b接收了,然后程序再向下走,输入c的值&w&。结果就会按顺序显示a,b,c的值,我们已经知道a='q',b='\n',c='w';所以结果就会显示两行。
如果我们加入getchar()会有什么结果呢?
我们再来看一下改进的程序:
1 #include&stdio.h&
2 #include&stdlib.h&
3 int main(void)
char a,b,c;
printf("please input num a:\n");
scanf("%c",&a);
getchar();
printf("please input num b:\n");
scanf("%c",&b);
getchar();
printf("please input num c:\n");
scanf("%c",&c);
printf("%c,%c,%c",a,b,c);
显示结果如下:
现在为什么会正常显示我们想要的结果呢?原因就是getchar()把enter键所表示的字符接收了,所以就会达到想要的效果了。
到现在你应该明白为什么会出现这种情况了吧!无非就是输入的规范问题,如果我们运行第二个程序,用另一种方法输入看看会是神马效果:
看到没?也可以获取想要的结果,但是程序并不是这么美观了,为什么会出现这种效果呢?
因为编译器规定输入的时候并不是立即回显,而是存到一个缓冲区里面。当遇到换行字符会释放缓冲区的数据,并清空缓冲区。
scanf()在读取数字时会跳过空格、制表符和换行符!
阅读(...) 评论()2643人阅读
(此贴对自己受用,来源网络,在此分享)在中有个重要的库函数getchar(),可从终端获得一个字符的ASCII码值。在终端输入字符时并非输入一个字符就会返回,而是在遇到回车换行前,所有输入的在C语言中有个重要的库函数getchar(),可从终端获得一个字符的ASCII码值。在终端输入字符时并非输入一个字符就会返回,而是在遇到回车换行前,所有输入的字符都会缓冲在键盘缓冲器中,直到回车换行一次性将所有字符按序依次赋给相应的变量,在这里一定要注意最后一个字符即'\n',该字符也会赋给一个相应的变量(当然这要你定义的用来接收字符的变量数比你输入的可见字符多一才可以)。
  其实,getchar()最典型的程序也就几行代码而已。本人所用的环境是DebianGNU/Linux,在其他系统下也一样。
  一、getchar的两点总结:
  1.getchar是以行为单位进行存取的。
  当用getchar进行输入时,如果输入的第一个字符为有效字符(即输入是文件结束符EOF,Windows下为组合键Ctrl+Z, Unix/Linux下为组合键Ctrl+D),那么只有当最后一个输入字符为换行符'\n'(也可以是文件结束符EOF,EOF将在后面讨论)时, getchar才会停止执行,整个程序将会往下执行。譬如下面程序段:
  while((c = getchar()) != EOF){ putchar(c);}
  执行程序,输入:abc,然后回车。则程序就会去执行puchar(c),然后输出abc,这个地方不要忘了,系统输出的还有一个回车。然后可以继续输入,再次遇到换行符的时候,程序又会把那一行的输入的字符输出在终端上。
  对于getchar,肯定很多初学的朋友会问,getchar不是以字符为单位读取的吗?那么,既然我输入了第一个字符a,肯定满足while循环(c = getchar()) != EOF的条件阿,那么应该执行putchar(c)在终端输出一个字符a。不错,我在用getchar的时候也是一直这么想的,但是程序就偏偏不着样执行,而是必需读到一个换行符或者文件结束符EOF才进行一次输出。
  对这个问题的一个解释是,在大师编写C的时候,当时并没有所谓终端输入的概念,所有的输入实际上都是按照文件进行读取的,文件中一般都是以行为单位的。因此,只有遇到换行符,那么程序会认为输入结束,然后采取执行程序的其他部分。同时,输入是按照文件的方式存取的,那么要结束一个文件的输入就需用到EOF (Enf Of File). 这也就是为什么getchar结束输入退出时要用EOF的原因。
  2.getchar()的返回值一般情况下是字符,但也可能是负值,即返回EOF。
  这里要强调的一点就是,getchar函数通常返回终端所输入的字符,这些字符系统中对应的ASCII值都是非负的。因此,很多时候,我们会写这样的两行代码:
  c = getchar();
  这样就很有可能出现问题。因为getchar函数除了返回终端输入的字符外,在遇到Ctrl+D(Linux下)即文件结束符EOF时,getchar ()的返回EOF,这个EOF在函数库里一般定义为-1。因此,在这种情况下,getchar函数返回一个负值,把一个负值赋给一个char型的变量是不正确的。为了能够让所定义的变量能够包含getchar函数返回的所有可能的值,正确的定义方法如下(K&R C中特别提到了这个问题):
  c = getchar();
  二、EOF的两点总结(主要指普通终端中的EOF)
  1.EOF作为文件结束符时的情况:
  EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符。
  (1)遇到getchar函数执行时,要输入第一个字符时就直接输入Ctrl+D,就可以跳出getchar(),去执行程序的其他部分;
  (2)在前面输入的字符为换行符时,接着输入Ctrl+D;
  (3)在前面有字符输入且不为换行符时,要连着输入两次Ctrl+D,这时第二次输入的Ctrl+D起到文件结束符的功能,至于第一次的Ctrl+D的作用将在下面介绍。
  其实,这三种情况都可以总结为只有在getchar()提示新的一次输入时,直接输入Ctrl+D才相当于文件结束符。
  2.EOF作为行结束符时的情况,这时候输入Ctrl+D并不能结束getchar(),而只能引发getchar()提示下一轮的输入。
  这种情况主要是在进行getchar()新的一行输入时,当输入了若干字符(不能包含换行符)之后,直接输入Ctrl+D,此时的Ctrl+D并不是文件结束符,而只是相当于换行符的功能,即结束当前的输入。以上面的代码段为例,如果执行时输入abc,然后Ctrl+D,程序输出结果为:
  abcabc
  注意:第一组abc为从终端输入的,然后输入Ctrl+D,就输出第二组abc,同时光标停在第二组字符的c后面,然后可以进行新一次的输入。这时如果再次输入Ctrl+D,则起到了文件结束符的作用,结束getchar()。
  如果输入abc之后,然后回车,输入换行符的话,则终端显示为:
  abc & & & & //第一行,带回车
  abc & & & & //第二行
  //第三行
  其中第一行为终端输入,第二行为终端输出,光标停在了第三行处,等待新一次的终端输入。
  从这里也可以看出Ctrl+D和换行符分别作为行结束符时,输出的不同结果。
  EOF的作用也可以总结为:当终端有字符输入时,Ctrl+D产生的EOF相当于结束本行的输入,将引起getchar()新一轮的输入;当终端没有字符输入或者可以说当getchar()读取新的一次输入时,输入Ctrl+D,此时产生的EOF相当于文件结束符,程序将结束getchar()的执行。字符都会缓冲在键盘缓冲器中,直到回车换行一次性将所有字符按序依次赋给相应的变量,在这里一定要注意最后一个字符即'\n',该字符也会赋给一个相应的变量(当然这要你定义的用来接收字符的变量数比你输入的可见字符多一才可以)。
  其实,getchar()最典型的程序也就几行代码而已。本人所用的环境是DebianGNU/Linux,在其他系统下也一样。
  一、getchar的两点总结:
  1.getchar是以行为单位进行存取的。
  当用getchar进行输入时,如果输入的第一个字符为有效字符(即输入是文件结束符EOF,Windows下为组合键Ctrl+Z, Unix/Linux下为组合键Ctrl+D),那么只有当最后一个输入字符为换行符'\n'(也可以是文件结束符EOF,EOF将在后面讨论)时, getchar才会停止执行,整个程序将会往下执行。譬如下面程序段:
  while((c = getchar()) != EOF){ putchar(c);}
  执行程序,输入:abc,然后回车。则程序就会去执行puchar(c),然后输出abc,这个地方不要忘了,系统输出的还有一个回车。然后可以继续输入,再次遇到换行符的时候,程序又会把那一行的输入的字符输出在终端上。
  对于getchar,肯定很多初学的朋友会问,getchar不是以字符为单位读取的吗?那么,既然我输入了第一个字符a,肯定满足while循环(c = getchar()) != EOF的条件阿,那么应该执行putchar(c)在终端输出一个字符a。不错,我在用getchar的时候也是一直这么想的,但是程序就偏偏不着样执行,而是必需读到一个换行符或者文件结束符EOF才进行一次输出。
  对这个问题的一个解释是,在大师编写C的时候,当时并没有所谓终端输入的概念,所有的输入实际上都是按照文件进行读取的,文件中一般都是以行为单位的。因此,只有遇到换行符,那么程序会认为输入结束,然后采取执行程序的其他部分。同时,输入是按照文件的方式存取的,那么要结束一个文件的输入就需用到EOF (Enf Of File). 这也就是为什么getchar结束输入退出时要用EOF的原因。
  2.getchar()的返回值一般情况下是字符,但也可能是负值,即返回EOF。
  这里要强调的一点就是,getchar函数通常返回终端所输入的字符,这些字符系统中对应的ASCII值都是非负的。因此,很多时候,我们会写这样的两行代码:
  c = getchar();
  这样就很有可能出现问题。因为getchar函数除了返回终端输入的字符外,在遇到Ctrl+D(Linux下)即文件结束符EOF时,getchar ()的返回EOF,这个EOF在函数库里一般定义为-1。因此,在这种情况下,getchar函数返回一个负值,把一个负值赋给一个char型的变量是不正确的。为了能够让所定义的变量能够包含getchar函数返回的所有可能的值,正确的定义方法如下(K&R C中特别提到了这个问题):
  c = getchar();
  二、EOF的两点总结(主要指普通终端中的EOF)
  1.EOF作为文件结束符时的情况:
  EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符。
  (1)遇到getchar函数执行时,要输入第一个字符时就直接输入Ctrl+D,就可以跳出getchar(),去执行程序的其他部分;
  (2)在前面输入的字符为换行符时,接着输入Ctrl+D;
  (3)在前面有字符输入且不为换行符时,要连着输入两次Ctrl+D,这时第二次输入的Ctrl+D起到文件结束符的功能,至于第一次的Ctrl+D的作用将在下面介绍。
  其实,这三种情况都可以总结为只有在getchar()提示新的一次输入时,直接输入Ctrl+D才相当于文件结束符。
  2.EOF作为行结束符时的情况,这时候输入Ctrl+D并不能结束getchar(),而只能引发getchar()提示下一轮的输入。
  这种情况主要是在进行getchar()新的一行输入时,当输入了若干字符(不能包含换行符)之后,直接输入Ctrl+D,此时的Ctrl+D并不是文件结束符,而只是相当于换行符的功能,即结束当前的输入。以上面的代码段为例,如果执行时输入abc,然后Ctrl+D,程序输出结果为:
  abcabc
  注意:第一组abc为从终端输入的,然后输入Ctrl+D,就输出第二组abc,同时光标停在第二组字符的c后面,然后可以进行新一次的输入。这时如果再次输入Ctrl+D,则起到了文件结束符的作用,结束getchar()。
  如果输入abc之后,然后回车,输入换行符的话,则终端显示为:
  abc&&&&&&&& //第一行,带回车
  abc&&&&&&&& //第二行
  //第三行
  其中第一行为终端输入,第二行为终端输出,光标停在了第三行处,等待新一次的终端输入。
  从这里也可以看出Ctrl+D和换行符分别作为行结束符时,输出的不同结果。
  EOF的作用也可以总结为:当终端有字符输入时,Ctrl+D产生的EOF相当于结束本行的输入,将引起getchar()新一轮的输入;当终端没有字符输入或者可以说当getchar()读取新的一次输入时,输入Ctrl+D,此时产生的EOF相当于文件结束符,程序将结束getchar()的执行。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4632次
排名:千里之外
(3)(1)(1)(1)(1)(1)是不是输入一串字符时,按回车把字符输到缓冲区时在最后加上了一个\N?
应为
while((c=getchar())!='\n')
printf("%c",c);
是在遇到换行符才结束.那一定是自己在我输的一串数后加了换行符?
还有为什么我去掉((c=getchar())的括号,变成while(c=getchar()!='\n')
输出结果不正确?
全部答案(共2个回答)
器对越界不会作检查,使用时为了知道在何处结束,它会加上一个'\0'在末尾,这样的话,如果判断是否结束的话就应该用 != '\0' 了.
使用函数:scanf("%s",str)
就没有问题了
但是记住,一定不要输入的字符数超过你定义的字符串的长度
首先先向楼主说明编写此题程序的核心与关键应该是运用C程序中的“循环语句部分”。程序如下:
#include&stdio.h&
void main()
int myfunc(int x)
/* 参数为要判断的数 */
for(i=2;i&x;i++)
问题出在scanf函数,当函数执行完毕时。键盘输入缓冲区中仍然未清空,这应该算是一个bug吧。在使用gets函数时,就会得到上次使用scanf时残留的信息。所以...
尿液中含VC++,真的要控制吃水果的量嘛?
大家还关注
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区

我要回帖

更多关于 c语言getchar和scanf 的文章

 

随机推荐