第8章 字符输入/输出和输入验证

发布于 2021-05-04  26 次阅读


8.1 单字符I/O:getchar()和putchar()

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

自从ANSI C标准发布以后,C就把头文件于使用getchar()和putchar()相关联。(它们其实不是真正的函数,被定义为供预处理器使用的宏)。

8.2 缓冲区

回显用户输入的字符后立即重复打印该字符是属于无缓冲(或直接)输入,即正在等待的程序可立即使用输入的字符。
对于该例,大部分系统在用户按下Enter键之前不会重复打印刚输入的字符,这种输入形式属于缓冲输入。用户输入的字符被收集并存储在了一个被称为缓冲区(buffer)的临时存储区,按下Enter后,程序才可使用用户输入的字符。
file
有了缓冲区:
(1)若干字符作为一个块进行传输比逐个发送这些字符节约时间。
(2)打错字符,可以通过键盘修正错误。当之后按下Enter时,传输的是正确的输入。
虽然缓冲输入好处很多,但是某些交互式程序也需要无缓冲。例如,游戏~
缓冲分为两类:完全缓冲I/O和行缓冲I/O完全缓冲输入指的是当缓冲区被填满时才刷新缓冲区(内容被发送至目的地),通常出现在文件输入中。缓冲区的大小取决于系统,常见的大小是512字节和4096字节。行缓冲I/O指的是再出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入,所以在按下Enter后次啊刷新缓冲区。
ANSI C决定把缓冲输入作为标准是因为一些计算机不允许无缓冲输入。无缓冲:IBM PC 兼容机上conio.h头文件用于回显无缓冲getche()和无回显无缓冲getch().UNIX系统使用ioctl()函数然后getchar()..
在ANSI C中用setbuf()和setvbuf()函数控制缓冲,但是受限于一些系统内部设置,这些函数可能不起作用。总之,ANSI没有提供调用无缓冲输入的标准方式,这意味着能否进行无缓冲输入取决于计算机系统。

8.3 结束键盘键入

因为#也不可避免的可能被使用,C提供了一个文本中使用不到的字符。

8.3.1 文件、流和键盘输入

文件(file)是存储器中存储信息的区域。
C是一门强大、灵活的语言,有许多用于打开、读取、写入和关闭文件的库函数。从较低层面上,C可以使用主机操作系统的基本文件工具直接处理文件,这些调用操作系统的函数被称为底层I/O(low-level I/O)。由于计算机系统不同,所以不可能为普通的底层I/O函数创建标准库,ANSI C也不打算这样做。在较高层面上,C还可以通过标准的I/O包(standard I/O package)来处理文件。这涉及创建用于处理文件的标准模型和一套标准的I/O函数。具体的C实现负责处理不同系统的差异,以便用户使用统一的界面。
不同的系统存储文件的方式不同,有些系统把文件的内容存储在一处,而文件相关的信息存储在另外一处;有些系统在文件徐鸿创建一份文件描述。在处理文件方面,有些系统使用单个换行符记行末尾,而其他系统可能使用回车和换行符的组合来表示末尾。有些系统使用最小字节来衡量文件的大小,有些系统则以字节块的大小来衡量。
如果使用标准的I/O包,就不用考虑这些差异。因此,可以使用if(ch == '\n')检查换行符。即使系统实际用回车符和换行符的组合来标记行末尾,I/O函数会在两种表示法之间相互转换。
从概念上看,C程序处理的是流而不是直接处理文件。流(stream)是一个实际输入或输出映射的理想化数据流。这意味着不同属性和不同种类的输入,由属性更统一的流来表示。打开文件的过程就是把流与文件相关联,而且读写都通过流来完成。
本章着重理解C把输入和输出设备视为存储设备上的普通文件,尤其是把键盘和显示视为每个C程序自动打开的文件。stdin流表键盘输入,stdout流表示屏幕输出。getchar()、putchar()、printf()和scanf()函数都是标准I/O包的成员,处理这两个流。
以上讨论的内容说明,可以用处理文件的方式处理的方式来处理键盘的输入。例如,程序读文件时要能检测文件的末尾才知道应在何处停止。因此,C的输入函数内置了文件结尾检测器。既然可以把键盘输入视为文件,那么也应该能使用文件结尾检测器结束键盘的输入。

8.3.2 文件结尾


擦肩而过的概率