C语言的单字符IO之getchar()和putchar()

来源:互联网 发布:mac收藏网页 编辑:程序博客网 时间:2024/05/17 01:15

C语言的单字符IO之getchar()和putchar()



图片来源-百度图片

引言

getchar()和putchar()每次只处理一个字符。你可能认为这种方法很低级,与我们的阅读方式相差甚远。但是,这种方法很适合计算机,而且这是绝大多数文本处理程序所用的核心方法。

示例分析

/* echo.c -- repeats input */#include <stdio.h>int main(void){    char ch;    while ((ch = getchar()) != '#')        putchar(ch);    return 0;}

该程序获取键盘输入的字符,并把这些字符发送到屏幕上。程序使用while循环,当读到#字符时停止。

自从ANSI C标准发布以后,c就把stdio.h头文件与使用getchar()和putchar()相关联,因此程序中要包含这个头文件(其实,getchar()和putchar()都不是真正的函数,它们被定义为供预处理器使用的宏)。运行程序后,与用户的交互如下:

Hello,there. I would[用户输入]Hello,there. I wouldlike a #3 bag of potatoes.[用户输入]like a

为什么输入的字符能直接在屏幕上显示?如果用一个特殊字符(如,#)来结束输入,就无法在文本中使用这个字符,是否有更好的方法输入?要回答这些问题,首先要了解C程序如何处理键盘输入,尤其是缓冲和标准输入文件的概念。

缓冲区

如果在一些老式系统运行上面的程序,你输入的文本时可能显示如下

HHeelllloo,,tthheerree..  II  wwoouullddlliikkee  aa  #

像这样回显用户输入的字符后立即打印重复打印该字符是属于无缓冲(或直接)输入,即正在等待的程序可立即使用输入的字符。对于该例,大部分系统用户按下Enter键之前不会重复打印刚输入的字符,这种输入形式属于缓冲输入。用户输入的字符被收集并存储在一个被称为缓冲区的临时存储区,按下ENTER键后,程序才可使用用户输入的字符。如下图所示,



无缓冲输入与缓冲输入-百度图片

为什么要有缓冲区?首先,把若干字符作为一个块进行传输比逐个发送这些字符节约时间。其次,如果用户打错字符,可以直接通过键盘修正错误。当最后按下ENTER键时,传输的是正确的输入。

缓冲输入有这么多好处,为什么还要使用无缓冲输入呢?因为一些交互式程序需要无缓冲输入。例如,在游戏中,你希望按下一个键就执行相应的指令。当你玩LOL的时候不会希望每次放技能都要按下ENTER,你的英雄才动作吧!!!因此缓冲输入与无缓冲输入都有用武之地。

缓冲分两类:完全缓冲I/O和行缓冲I/O。完全缓冲输入指的是当缓冲区填被满时才刷新缓冲区(内容被发送至目的地),通常出现在文件输入中。缓冲区的大小取决于系统,常见的大小是512字节和4096字节。行缓冲I/O指的是在出现换行符时刷新缓冲区,键盘输入通常是行缓冲输入,所以按下ENTER键后才刷新缓冲区。

那么使用缓冲输入还是无缓冲输入?ANSI C和后续的C标准都规定输入是缓冲的,不过最初K&R把这个决定权交给了编译器的编写者。

ANSI 没有提供调用无缓冲输入的标准方式,这意味着是否能进行无缓冲输入取决于计算机系统。


参考资料:

[1] 史蒂芬・普拉达. C Primer Plus (第6版) 中文版[M]. 人民邮电出版社, 2016.