第八章 字符输入/输出和输入确认
8.1 单字符I/O:getchar()和putchar()
- #include<stdio.h> //回显
- int main(void)
- {
- char ch;
- while((ch=getchar())!='#')
- putchar(ch);
- return 0;
- }
8.2 缓冲区
当您在一些系统上运行前面的程序时,您所输入的文本立即回显。但是在大多数系统上,在您按下回车键之前什么都不会发生。
输入字符的立即回显是非缓冲或直接输入的一个实例,它表示您所键入的字符对正在等待的程序立即变为可用。
延迟回显是缓冲输入的实例,在这种情况下您所键入的字符被收集并存储在一个被称为缓冲区的临时存储区中。按下回车键可使您所键入的字符块对程序变为可用。
为什么需要缓冲区
首先,将若干个字符作为一个块传输比逐个发送这些字符耗费的时间少。
其次,如果您输入有误,就可以使用您的键盘更正功能来修正错误。
另一方面,一些交互性的程序需要非缓冲输入。
缓冲分为两类:完全缓冲I/O和行缓冲I/O。
对完全缓冲输入来说,缓冲区满时被清空。这种类型的缓冲通常出线在文件输入中。缓冲区的大小取决于系统。
对行缓冲来说,遇到一个换行字符时被清空缓冲区。硬盘输入是标准的行缓冲。
不存在调用非缓冲输入的标准ANSI方式;使用的方法取决于计算机系统。
8.3 终止键盘输入
8.3.1 文件、流和键盘输入
文件是一块存储信息的存储器区域。
从概念上说,C程序处理一个流而不是直接处理文件。
流是一个理想化的数据流,实际输入或输出映射到这个数据流。
C对待输入和输出设备与其对待存储设备上的普通文件相同。
键盘输入由一个被称为stdin的流表示,而到屏幕上的输出由一个被称为stdout的流表示。
8.3.2 文件结尾
计算机操作系统需要某种方式来断定每个文件起始和结束的位置。
检测文件结尾的一种方法是在文件中放置一个特殊字符来标志结尾。
第二种方法是让操作系统存储文件大小的信息。
对于这两种不同的方法,C的处理方法是让getchar()函数在到达文件结尾时返回一个特殊值,而不去管操作系统是如何检测文件结尾的。赋予该值的名称是EOF。
通常EOF在stdio.h文件中定义为-1。
- #include<stdio.h>
- int main(void)
- {
- int ch;
- while((ch=getchar())!=EOF)
- putchar(ch);
- return 0;
- }
变量ch从char类型改变为int类型。这是因为char变量可以由范围在0到255中的无符号整数来表示,但EOF可能具有数值-1。该值对无符号char变量是不可能的值,但对int则是可能的。
输入重定向使您的程序能够使用文件代替键盘作为输入,输出重定向则使程序能够使用文件代替屏幕作为输出。
8.4 创建一个更友好的用户界面
- #include<stdio.h>
- int main(void)
- {
- int guess=1;
- while(getchar()!='y')
- printf("Well,then,is it %d?\n",++guess);
- printf("I knew I\n");
- return 0;
- }
BUG:程序读取n响应并把它看作是您的一次否定,然后读取换行字符并把它也看作是您的一次否定。
一种解决方案是使用一个while循环来丢弃输入行的其余部分,包括换行符。
while(getchar()!='\n')
continue;
许多程序使用getchar()来逐个字符地读取输入。通常,系统使用行缓冲输入,这意味着输入的内容在您按下回车键时传输给程序。此时还将传输一个编程时需要注意的换行字符。ANSI C将缓冲输入作为标准。