永发信息网

请问:关于C语言中getc(stdin) 读取键盘缓冲区中的输入的问题?

答案:1  悬赏:40  手机版
解决时间 2021-07-31 12:46

C语言中:getc(stdin) 能取得键盘缓冲区中的一个字符:

如:

#include<stdio.h>

void main(void)
{
char a;
a=getc(stdin);
printf("%c",a);

}

以下是stdio.h 中的部分源码:

struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};


typedef struct _iobuf FILE;

_CRTIMP int __cdecl _filbuf(FILE *);

#define getc(_stream) (--(_stream)->_cnt >= 0? 0xff & *(_stream)->_ptr++ : _filbuf(_stream))

#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])

_CRTIMP int __cdecl getc(FILE *);

_CRTIMP extern FILE _iob[];

从上面我们知道,getc()的参数是 一个可以指向 FILE 类型的变量,同时也知道 getc()的实现

也知道 getc(stdin) 中的stdin 是(&_iob[0])。

所以我们知道 :

_stream=&_iob[0]; 从上面我们知道_iob[] 是一个FILE数组,

a=getc(stdin); 当程序执行到这里时,是怎么确定 _iob[0]._cnt的值的呢?

即:

问题1: --(_stream)->_cnt >= 0 中(_stream)->_cnt的值是那里来的?

问题2:0xff & *(_stream)->_ptr++,_ptr _ptr值是怎么来的?

问题3:_filbuf(_stream)) 是什么意思?

主要要问:

getc() 是怎么实现从 键盘缓冲区中取得一个字符的?

最佳答案

问题一:


首先得搞清楚stdin是什么:


#define stdin (&_iob[0])


然后再看_iob[0]:


#define _IOB_ENTRIES 20


typedef struct _iobuf FILE;


FILE _iob[_IOB_ENTRIES] = {



{ _bufin, 0, _bufin, _IOREAD | _IOYOURBUF, 0, 0, _INTERNAL_BUFSIZ },



{ NULL, 0, NULL, _IOWRT, 1, 0, 0 },



{ NULL, 0, NULL, _IOWRT, 2, 0, 0 },


};


这是一个全局的FILE结构体数组。肯定在初始化的时候就已经成这样了。


所以第一个问题解决。


问题二也就解开了。


问题三:


_filbuf(_stream)) 中_filbuf是个函数,_stream是stdin也就是FILE _iob[0].


再看获取IO输入的调用流程:


getc的整个流程:
.exe!main()
.exe!_filbuf(_iobuf * str=0x0043d1c0) // #define getc( param ) _filbuf( param )
.exe!_read(int fh=0, void * buf=0x0043e800, unsigned int cnt=4096)
kernel32.dll!_ReadFile@20()
kernel32.dll!_ReadConsoleA@20()
kernel32.dll!_ReadConsoleInternal@32()
ntdll.dll!_CsrClientCallServer@16()
ntdll.dll!_ZwRequestWaitReplyPort@12()
ntdll.dll!_KiFastSystemCall@0()



_KiFastSystemCall@0()的反汇编代码是:
mov edx, esp
sysenter // 进驱动



因此 _filbuf就负责一直等待console的输入缓冲区里面有字符输入,然后填到FILE的buf里面,也就是(_stream)->_ptr所指向的这个缓冲区.

(_stream)->_cnt就是在filbuf里面设置的,读取了io,填到buff里面后,会修改这个cnt,表示buff里面有多少字符.


我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
开始对他变得无所谓了这是怎么回事呢?
怎么会有陌生人偷我的菜啊
怎样让自己在感情上不受伤?
从沈阳坐飞机到巴厘岛要多长时间
显卡95驱动问题
韩国的哪里最好玩?
魔兽世界中突袭巴什伊尔码头任务 我怎么接不
龙沙区齐齐哈尔艾尼尔珠宝地址有谁知道?有点
什么图标最不好点亮?
请问Would you like to join my team?是什么
上卫校要学些什么?
如何提高精气神?现在工作压力很大,每天昏昏沉
阿修罗要不要学空中连斩?
怎样才可以把守护甜心图片放到空间?
新洲区武汉新洲区宏达电动工具商行地址有谁知
推荐资讯
揣摩列句特点,发挥想象,根据提示将句子补充完
电信,联通,移动那个网络好???(南京地区
项城市周口百万电子竞技俱乐部在什么地方啊,
dnf河南3区 羽灵护肩多少钱啊?
黄钻LV1升到LV7需要多少人民币?
江汉区武汉中国银行(友谊支行)(装修中)怎么去
为什么我的电脑待机后,要按下电源开关才能启
淇滨区鹤壁视特佳近弱视防控中心地址在哪,我
刚性平面问题
咸丰为什么会信一个无赖,而这个无赖又是谁?
N81相机不被支持咋办呢?
手机家园在电脑上有吗?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?