getchar()和putchar()吸收回车问题


getchar()

头文件:#include <stdio.h>

【功能】读取一个字符,并返回它的ASCII码值

如果用户在按回车键之前输入了不只一个字符,其他字符会保留在键盘缓冲区中,等待后续系统调用读取。也就是说,后续的系统调用不会等待用户按键,而是直接读取缓冲区中的字符,直到缓冲区的字符读取完毕后,才等待用户按键。


【参数】该函数没有参数。

【返回值】读取的字符的ASCII码

【函数原型】 #define getchar() getc(stdin)

说明:本质是无参宏定义,但由于长相酷似函数,所以我们可以把gatcahr()当成函数看

【代码实践】

getchar是输入字符的函数,括号内不能有参数


getchar('a');    //报错


如果将getchar()执行时写入整数会怎样?

系统会将整数认为是字符,如下例:输入了0,系统会将0认为是字符'0',输出字符'0'的%d为:48


	char a;
 	a = getchar();	//输入0
 	printf("%c,%d\n",a,a);	//0,48


那只有0~9可以作为字符,如果输入个大于9的数呢?

系统会取第一个数字作为输入的字符,如下例:输入23,系统只识别2,不识别3,并将2作为字符'2'输出,输出字符'2'的%d为:50


	char a;
 	a = getchar();	//输入23
 	printf("%c,%d\n",a,a);	//2,50


如果输入好多个字符呢?

系统只取第一个字符,剩下的字符不管。如下例:输入abc,系统只识别a,不识别bc,通过输出结果也可看出来,请自行体会。


	char a;
 	a = getchar();	//输入abc 
 	printf("%c,%d\n",a,a);	//a,97 



如果用户在按回车键之前输入了不只一个字符,其他字符会保留在键盘缓冲区中,等待后续系统调用读取。也就是说,后续的系统调用不会等待用户按键,而是直接读取缓冲区中的字符,直到缓冲区的字符读取完毕后,才等待用户按键。

这段话怎么理解呢?我们用代码来帮助理解。

下列代码是这样的:我们通过while循环从键盘中输入一个字符,如果读取到输入的字符不是'k',就输出它(需要按回车键),当输入'k'时停止循环。那什么是保留到键盘缓冲区呢?我们知道getchar是一次读取一个字符,需要按回车系统才会认为我们结束了本次输入,当我们不按回车时系统就不会认为我们输完了,在这个时候我们如果输入abcdeg,系统会只调用一次getchar()读取一个字符'a',并将'b'、'c'、'd'、'e'、'f'、'g'、'\n'依次放入到键盘缓冲区里,当我们按下回车,系统就会读取a并输出'a',然后不让我们输入了,转去调用getchar()读取缓冲区里的'b',再输出'b',然后再调用getchar()读取缓冲区里的'c',再输出'c',直到调用getchar()读取完并输出完本次'a'、'b'、'c'、'd'、'e'、'f'、'g'、'\n'所有字符为止。输出完后,由于并没有碰到'k',所以系统会让我们继续输入,我们输入:hijklmn,按下回车,系统会依次调用getchar()读取'h',输出'h';调用getchar()读取'i',输出'i';调用getchar()读取'j',输出'j';调用getchar()读取'k',此时系统发现输入的字符等于'k',不满足循环条件了,便会退出while循环而且不会输出'k'。为什么会退出循环?是因为我们程序就是这样设计的。因此这一次系统输出的是:hij。当我们按下任意按键时,程序会退出。



#include<stdio.h>
void main( ){
    int c;
    while( (c=getchar()) != 'k' ) //从控制台流中读取字符,直到按'k'结束
        printf ("%c", c);  //输出读取内容
}


由于上段代码中printf("%c",c);输出的是一个字符,因此我们可以用putchar(c)替换掉它,效果与其一模一样


#include<stdio.h>
void main( ){
    int c;
    while( (c=getchar()) != 'k' ) //从控制台流中读取字符,直到按'k'结束
        putchar(c);
       // printf ("%c", c);  //输出读取内容
}


【运行结果】


abcdefg    //输入:abcdefg 回车
abcdefg    //依次从键盘缓存区中读取abcdefg和\n,并依次输出:abcdefg和\n
hijklmn    //输入:hijklmn 回车
hij        //依次从键盘缓存区读取hij,并依次输出;读取到k时退出循环
--------------------------------
Process exited after 6.641 seconds with return value 107
请按任意键继续. . .


如果条件改为:


while( (c=getchar()) != '\a' )


那么'\a'是控制字符 - 响铃,由于键盘上没有这个键,所以我们无论输入多少字符都不会结束程序的运行(除非手动点右上角的

×退出)。

冷知识:

可以这样用吗?


 while( (printf("%c",getchar())) != '\n' ) ; 


可以的,while里可以调用函数,此语句的意思是输入字符并输出,当读取的字符不是\n时就一直循环,当读取到'\n'时结束循环。但是由于我们不知道printf的返回值,所以暂时不要这样用(printf的返回值暂时无需研究)


	while(	putchar(getchar()) );


可以的,不过同样不知道putchar的返回值什么时候是0,所以成了死循环,不断输入字符、按下回车、调用getchar()读取字符、调用putchar()输出字符。



putchar()

头文件:#include<stdio.h>

函数与形参类型: int putchar(int ch)

功能:输出一个字符,可以是字符常量或字符变量

返回值:字符的ASCLL码

1.输出字符常量:

可以输入整型或字符型,系统会将65、 0101 、0x41这三个不同进制的ASCII码会转化为字符型常量'A'。


	putchar('A');  //A
    putchar(65);  //A
	putchar(0101);  //A
	putchar(0x41);  //A


2.输出字符变量:


	char ch = 'A';
	putchar(ch);  //A
	
	int a = 65 ,b = 0101 , c = 0x41;
	putchar(a);  //A
	putchar(b);  //A
	putchar(c);  //A



putchar()与getchar()混合使用:

为什么可以这样用?因为getchar的返回值是输入字符的ASCII码值。

putchar()基本形式:输入8,调用getchar()读取'8',输出'8'


	int c = getchar(); //8
	
    putchar(c);    //8


上述写法等价于下面写法

这种写法省去了定义c变量,可以直接输入并输出一个字符


    putchar(getchar());     //1
	printf("%c",getchar());   //2 与1等价


函数的实参可以是函数?这叫函数的嵌套调用吗

输入字符,键盘调用getchar()读取一个字符,调用了4次,然后调用putchar()输出1个字符,调用4次。


#include<stdio.h>

int main( ){
	
	putchar(getchar());      
	putchar(getchar()); 
	putchar(getchar()); 
	putchar(getchar()); 
       
    return 0;
}


【运行结果】


abcdefg    //输入
abcd        //输出


上述代码等价于下面的代码


#include<stdio.h>

int main( ){
	
	int i=4;
	
	while(i--)	//循环4次 
	{
		putchar(getchar());  
	}

    return 0;
}


【运行结果】


123456789    //输入
1234        //输出


实例:

依次输入两个字符的值:5和6并换行输出他俩


#include<stdio.h>
#include<math.h>

int main( ){

	printf("请输入元素a的值:");
	int a = getchar() ;	//输入:5 回车 
	getchar();		//吸收掉回车  
	printf("请输入元素b的值:");
	int b = getchar();	//输入:6 回车 
	
	putchar(a);	//输出a 
	putchar('\n');	//换行 
	putchar(b);	//输出b 
	putchar('\n');	//换行 

    return 0;
}


【运行结果】

注意:这里的输入和输出,都是数字字符,本质是字符!!!


请输入元素a的值:5
请输入元素b的值:6
5
6



假设1:

如果在getchar输入完a以后,不吸收回车,那么系统在输出a之后,将不会让我们输入b,而是把回车 即'\n'赋值为b,再输出b


#include<stdio.h>
#include<math.h>

int main( ){

	printf("请输入元素a的值:");
	int a = getchar() ;	//输入:5 回车 
//	getchar();		//吸收掉回车  
	printf("请输入元素b的值:");
	int b = getchar();	//输入:6 回车 
	
	putchar(a);	//输出a 
	putchar('\n');	//换行 
	putchar(b);	//输出b 
	putchar('\n');	//换行 
	
	printf("b元素的ASCII码是:%d",b);
    return 0;
}



请输入元素a的值:5    //输入a:5
请输入元素b的值:5    //系统将回车赋给b,再输出a,(本行的5并不是我输入的)
                    //执行putchar('\n') 换行
                    //输出b (此时的b是'\n')
b元素的ASCII码是:10  //执行putchar('\n') 换行,再输出b的ASCII码:10(对应'\n')


假设2:

如果将两条putchar换行语句的单引号变为双引号,就不是换行语句了,因为putchar只能输出字符


	putchar("\n");	//变为双引号就不可以换行了



请输入元素a的值:5
请输入元素b的值:6
5$6$



(完)