字符输入函数getchar(),scanf(),getche(),getch()的比较

原文链接:http://www.juzicode.com/archives/4024

说明:本文的例子用dev-c++5.9.2测试,如果用vs2015 getche()、getch()需要包含”conio.h”头文件。

先看一个关于获取输入的例子,这个例子原意是当每输入一个字符,变量i自增1并打印,当输入的字符为q时退出循环:

//juzicode.com;vx:桔子code 
//dev-c++5.9.2 
#include "stdio.h"
int main(void)
{
    char ch;
    int i = 0;
    printf("输入字符:");
    while( (ch = getchar()) !='q') 
    {
        printf(" i=%d\n",i++);
    } 	
    return 0;
}

咋一看好像没什么问题,编译、运行看看结果如何:

输入字符:x
 i=0
 i=1
y
 i=2
 i=3
z
 i=4
 i=5

从运行结果看,每输入一个字符,while循环却执行了2次,比如输入x,打印i的语句执行了2次。为了观察实际输入的是什么字符,在每个循环中增加ch字符的打印,为了方便观察不打印字符内容而是打印其ASCII值,修改后的程序是这样的:

//juzicode.com;vx:桔子code
//dev-c++5.9.2  
#include "stdio.h"
int main(void)
{
    char ch;
    int i = 0;
    printf("输入字符:");
    while( (ch = getchar()) !='q') 
    {
        printf(" ch=%d\n",ch);
        printf(" i=%d\n",i++);
    } 	
    return 0;
}

运行结果:

输入字符:x
 ch=120  //输入字符x的ASCII值
 i=0
 ch=10   //“自动增加"字符的ASCII值
 i=1
y
 ch=121
 i=2
 ch=10
 i=3

从上述结果可以看到,每次输入一个字符,就相应的多出一个ASCII值为10的字符,通过ASCII表可以知道值为10的字符为换行符,所以可以看到getchar()实际非常“忠实地”读出了所有的字符,包括换行符,这一点和我们惯用的scanf()函数”过滤掉”换行符差异比较大。将上述代码中的getchar()改为scanf()函数后:

//juzicode.com;vx:桔子code 
//dev-c++5.9.2 
#include "stdio.h"
int main(void)
{
    char ch;
    int i = 0;
    printf("输入字符:");
    scanf("%c",&ch); 
    while( ch  !='q') 
    {
        printf(" ch=%d\n",ch);
        printf(" i=%d\n",i++);
    	scanf("%c",&ch); 
    } 	
    return 0;
}

运行结果:

输入字符:x
 ch=120
 i=0
 ch=10
 i=1
y
 ch=121
 i=2
 ch=10
 i=3

从运行结果看,scanf()函数获取单个字符时和getchar()效果一样,实际上也解析到了换行符,这和平常我们使用scanf()获取输入时”过滤掉”换行符看起来是”有差异”的。

获取字符输入除了getchar()、scanf(),还有getch()、getche()等函数,接下来我们来看下如果使用getche()函数会是什么结果:

//juzicode.com;vx:桔子code 
//dev-c++5.9.2 
#include "stdio.h"
int main(void)
{
    char ch;
    int i = 0;
    printf("输入字符:");
    while( (ch = getche()) !='q') 
    {
        printf(" ch=%d\n",ch);
        printf(" i=%d\n",i++);
    } 	
    return 0;
}

运行结果:

输入字符:x ch=120
 i=0
y ch=121
 i=1
z ch=122
 i=2
 ch=13
 i=3

从实际运行结果看,getche()函数输入单个字符就能导致循环执行一次,并不需要等待换行符才执行一次循环,说明getche()函数是从键盘直接获取输入的,而getchar()需要等待换行符的方式实际是从缓冲区获取输入的。需要注意的是getche()函数将换行符解析成了值为13的LF,和getchar()将换行符解析成值为10的CR,二者是有区别的。

接下来再看下getch()函数:

//juzicode.com;vx:桔子code 
//dev-c++5.9.2 
#include "stdio.h"
int main(void)
{
    char ch;
    int i = 0;
    printf("输入字符:");
    while( (ch = getch()) !='q') 
    {
        printf(" ch=%d\n",ch);
        printf(" i=%d\n",i++);
    } 	
    return 0;
}

运行结果:

输入字符: ch=120
 i=0
 ch=121
 i=1
 ch=122
 i=2
 ch=13
 i=3

从运行结果看getch()和getche()的差别仅在于是否在控制台回显输入的字符,上面代码运行时实际依次输入了”x,y,z,换行”,从控制台可以看到并没有回显输入的这些字符。

小结:
1、getchar()和scanf()都是从缓冲区获取输入,缓冲区中没有换行符前函数一直处于等待状态。
2、getch()和getche()函数直接从按键获取,只要有单个按键按下,函数立即执行结束。
3、getch()和getche()的差异在于前者不回显输入的字符。
4、getchar()和scanf()将换行符解析为LF(10),getch()和getche()将换行符解析为CR(13)。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注