字符输入函数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)。