示例——一个简单的回显程序:
/*echo.c---重复输入*/
#include<stdio.h>
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来说,遇到一个换行符时将被清空缓冲区。键盘输入是标准的行缓冲,因此按下回车键将清空缓冲区。
文件、流和键盘输入
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<stdio.h>
int main(void)
{
char ch;
while((ch=getchar())!=EOF)
putchar(ch);
return 0;
}
要对键盘输入使用此程序,需要一种键入EOF字符的方式。大多数unix系统上在一行的开始键入Ctrl+D会导致传送文件尾信号。许多微型计算机将一行的开始位置键入的Ctrl+Z识别为文件尾信号,还有一些则把任意位置的Ctrl+Z解释成文件尾信号(正在写这篇博文的笔记本是将一行开始的Ctrl+Z当作文件尾信号)。
重定向和文件
echo_eof //从键盘获取输入(不使用重定向)
echo_eof < words //输入重定向,从一个名为words的文本文件获取输入
echo_eof > mywords //输出重定向,建立一个名为mywords的新文件,然后将echo_eof的输出(来自键盘输入)重定向到该文件。 //如果已经具有一个名为mywords的文件,将删除该文件然后用新的文件代替之。 echo_eof < words > savewords //组合重定向。
使用缓冲输入时,需要按下回车键提交您的输入,这一动作还传输一个程序必须处理的换行符。可以通过下面的while循环舍弃输入行的其余部分来解决这个问题:
while(getchar()!='\n')
continue; //跳过输入行的剩余部分
如果混用scnaf()和getchar()函数,那么当调用getchar()之前scanf()恰好在输入中留下一个换行符时,就会产生问题。然而,如果知道这个问题,就可以在编程中解决它。程序通常期望某种特定形式的输入。您可以通过设想用户可能翻的输入错误并令程序处理这些错误来使程序更加健壮和对用户更加友好。