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

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 would
like a #3 bag of potatoes.[用户输入]
like a

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

缓冲区

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

HHeelllloo,,tthheerree..  II  wwoouulldd
lliikkee  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.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Galaxy_Robot

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值