C Primer Plus 第八章——字符输入/输出和输入确认

示例——一个简单的回显程序:

/*echo.c---重复输入*/
#include
int main(void)
{
char ch;
while((ch=getchar())!='#')
putchar(ch);
return 0;
}
       程序运行后,在回显输入之前必须键入完整的一行。这种延迟回显时缓冲(buffered)输入的实例,这种情况下您所键入的字符被手机并存储在一个被称为缓冲区(buffer)的临时存储区域中。

       为什么需要缓冲区?首先,将若干个字符作为一个块传输比逐个发送这些字符耗费的时间少。其次,如果您输入有误,就可以使用您的键盘更正功能来修改错误。当最终按下回车键时,就可以发送正确的输入。

       一些交互性的程序需要非缓冲(unbuffered)输入,它表示您所键入的字符对正在等待的程序立即变为可用。

       缓冲分为两类:完全缓冲(fully buffered)I/O和行缓冲(line-buffered)I/O。对完全缓冲输入来说,缓冲区满时被清空(内容被发送至其目的地)。这种类型的缓冲通常出现在文件输入中。缓冲区的大小取决于系统,但512字节和4096字节是常见的值。对行缓冲I/O来说,遇到一个换行符时将被清空缓冲区。键盘输入是标准的行缓冲,因此按下回车键将清空缓冲区。

文件、流和键盘输入

       文件(file)是一块存储信息的存储器区域。通常,文件被保存在某种类别的永久存储器上。C语言具有许多用于打开、读、写和关闭文件的库函数。在一个级别上,它可以使用宿主操作系统的基本文件工具来处理文件。这被称为低级I/O(low-level I/O)。由于计算机系统之间存在差异,所以不可能创建一个通用的低级I/O函数的标准库。C还以第二种级别处理文件,称为标准I/O包(standard I/O package)。这包括创建用于处理文件的I/O函数的标准模型和标准集。在这一较高级别上,系统之间的差异由特定的C实现来处理,所以您与之打交道的是一个统一接口。
       从概念上说,C程序处理一个流而不是直接处理文件。流(stream)是一个理想化的数据流,实际输入或输出映射到这个数据流。这意味着具有不同属性的多种类型输入由流表示,会具有更多同一属性。于是打开文件的过程就成为将流与文件相关联,并通过流进行读写的过程。
       C对待输入和输出设备与其对待存储设备上的普通文件相同。特别的是,键盘和显示设备作为每个C程序自动打开的文件来对待。键盘由一个被称为stdin的流表示,而到屏幕(或电传打字机、或其他输出设备)上的输出由一个被称为stdout的流表示。

C输入函数装备有一个内置的文件尾检测器。因为键盘输入是像文件一样被看待的,所以也应该能使用该文件尾检测器来终止键盘输入。

       检测文件截尾的两种方法:1、使用内嵌的Ctrl+Z字符来标志文件结尾。2、让操作系统存储文件大小的信息。如果一个文件具有3000字节,而且程序已经读取了3000字节,则该程序就到达了文件尾。对于这两种不同的方法,C的处理方法是让getchar()函数在到达文件结尾时返回一个特殊值,而不管操作系统是如何检测文件结尾的。赋予该值的名称是EOF(End Of File,文件尾)。scanf()函数检测到文件尾时也返回EOF。通常EOF在stdio.h文件中定义为  #define EOF (-1),因为通常情况下getchar()函数返回一个0到127之间的值。在判断语句中将getchar()的返回值与EOF进行比较可以检测是否到达文件结尾。

while((ch=getchar())!=EOF)
重写后的基本读取和回显程序:

//echo_eof.c --重复输入,直到文件结尾
#include
int main(void)
{
char ch;
while((ch=getchar())!=EOF)
putchar(ch);
return 0;
}
       要对键盘输入使用此程序,需要一种键入EOF字符的方式。大多数unix系统上在一行的开始键入Ctrl+D会导致传送文件尾信号。许多微型计算机将一行的开始位置键入的Ctrl+Z识别为文件尾信号,还有一些则把任意位置的Ctrl+Z解释成文件尾信号(正在写这篇博文的笔记本是将一行开始的Ctrl+Z当作文件尾信号)。

重定向和文件

        程序如何了解在哪里寻找其输入?默认情况下,使用标准I/O包的C程序将标准输入作为输入源,这就是前面标识的stdin流。然而也可以告诉程序从文件而不是键盘寻求其输入。令程序与文件一同工作有两种方式。一种方式是明确地使用打开文件、关闭文件、读文件、写文件等等的专门函数(第13章讨论)。第二种方式是使用一个设计用于与键盘和屏幕共同工作的程序,但是使用不同通道重定向(redirect)输入和输出,例如输入到文件和从文件中输出。换句话说,就是将stdin流重新分配至文件。getchar()程序继续从该流中读取数据,而不真正关心是从何处获取其数据。
       <和>是Unix、Linux和DOS的重定向运算符。重定向运算符讲一个可执行(executable)程序(包括标准的操作系统命令)与一个数据文件连接起来(不能用于一个数据文件与另一个数据文件的连接,也不能用于一个程序和另一个程序的连接)。在Unix、Linux或DOS中使用重定向的示例如下,假设已经编译了echo_eof程序,并将它的可执行版本放在一个名为echo_eof的文件中(或在DOS系统上为echo_eof.exe):
echo_eof   //从键盘获取输入(不使用重定向)
echo_eof < words  //输入重定向,从一个名为words的文本文件获取输入
echo_eof > mywords  //输出重定向,建立一个名为mywords的新文件,然后将echo_eof的输出(来自键盘输入)重定向到该文件。                       //如果已经具有一个名为mywords的文件,将删除该文件然后用新的文件代替之。                                        echo_eof < words > savewords  //组合重定向。
C Primer Plus 第八章——字符输入/输出和输入确认_第1张图片
       使用缓冲输入时,需要按下回车键提交您的输入,这一动作还传输一个程序必须处理的换行符。可以通过下面的while循环舍弃输入行的其余部分来解决这个问题:
while(getchar()!='\n')
continue;                  //跳过输入行的剩余部分
 如果混用scnaf()和getchar()函数,那么当调用getchar()之前scanf()恰好在输入中留下一个换行符时,就会产生问题。然而,如果知道这个问题,就可以在编程中解决它。程序通常期望某种特定形式的输入。您可以通过设想用户可能翻的输入错误并令程序处理这些错误来使程序更加健壮和对用户更加友好。



你可能感兴趣的:(C,C,Primer,Plus)