缓冲区 Buffer
int main(void)
{
char ch;
while((ch = getchar()) != '#')
putchar(ch);
return 0;
}
无缓冲输入
输入一个字符,程序立即响应
缓冲输入
输入的字符被收集并存储在缓冲区(buffer) 中。按下Enter键后数据被发往程序,缓冲区被刷新。缓冲输入要求按下Enter键后发送输入,这一动作也传送了换行符。
无缓冲输入的好处
按下一个按键后程序就可以立即响应
缓冲输入的好处
1 把若干字符作为一个块进行传输比逐个发送单个字符节约时间。
2 如果打错字符,可以直接通过键盘修正错误。
缓冲分为两类:完全缓冲I/O和行缓冲I/O。
完全缓冲I/O输入指的是当缓冲区被填满时刷新缓冲区,通常出现在文件输入中。缓冲区的大小取决于系统,常见的大小是512字节和4096字节。
行缓冲I/O指的是在出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入,所以在按下Enter键后刷新缓冲区。
结束键盘输入
文件、流、和键盘输入
文件(file) 是存储器中储存信息的区域。通常,文件都保存在某种永久存储器中(如,硬盘、U盘或DVD等)。程序对文件的操作通常有四种:打开open、读取read、写入write、关闭close。
从较低层面上,C可以使用主机操作系统的基本文件工具直接处理文件,这些直接调用操作系统的函数被称为底层 I/O (low-level I/O)。由于计算机系统各不相同,所以不可能为普通的底层I/O函数创建标准库,ANSI C也不打算这样做。
C通过 标准I/O包(standard I/O package)来处理文件。这涉及创建用于处理文件的标准模型(流模式)和一套标准I/O函数。这样就可以使用统一的方式来处理不同系统的文件而不必管它们之间的差异。
从概念上看,C程序处理的是流而不是直接处理文件。流(stream) 是一个实际输入或输出映射的理想化数据流。这意味着不同属性和不同种类的输入,由属性更统一的流来表示。于是,打开文件的过程就是把流与文件相关联,而且读写也通过流来完成。
stdin流和stdout流
C把输入和输出设备视为存储设备上的普通文件。尤其把键盘和显示设备视为每个C程序自动打开的文件,这样就可以用处理文件的方式来处理键盘输入和屏幕输出。stdin流表示键盘输入,stdout流表示屏幕输出。getchar()、putchar()、printf()和scanf()函数都是标准I/O包的成员,可用来处理这两个流。
文件结尾
C 的输入函数内置了文件结尾检测器
计算机操作系统以某种方式判断文件的开始和结束
- 一种方法是,在文件末尾放一个特殊的字符标记文件结尾。
- 一种方法是记录文件大小,程序读到相应大小便认为是文件结尾
无论操作系统实际使用何种方法检测文件结尾,用getchar()和scanf()读取文件检测到文件结尾时将返回EOF(end of file)。EOF定义在 stdio.h 中。
为什么EOF定义为-1?
getchar() 函数的返回值对应标准字符集,通常是正数。所以-1可用于标记文件结尾。
while ((ch = getchar()) != EOF) //检测文件结尾
键盘模拟文件结尾
大多数UNIX和Linux 系统中,在一行开始处按下Ctrl+D会传输文件结尾信号。许多微型计算机系统都把一行开始处的Ctrl+Z 识别为文件结尾信号,一些系统把任意位置的Ctrl+Z 解释成文件结尾信号。
#include<stdio.h>
int main(void){
char ch;
while ((ch = getchar()) != EOF)
putchar(ch);
return 0;
}
重定向和文件
输入input:进行read操作,将数据读取到程序中
输出output:进行write操作,从程序往外部设备写出数据。
默认情况下,C程序使用标准I/O包查找标准输入(stdin流)/标准输出(stdout流)作为输入源/输出目标。 C程序默认stdin流表示键盘输入,stdout流表示屏幕输出。
程序可以通过两种方式使用文件。
- 显式使用特定的函数打开文件、关闭文件、读取文件、写入文件等。
- 设计能与键盘和屏幕互动的程序(如控制台),通过不同的渠道重定向输入和输出。也就是 把stdin流 和stdout流重新赋给文件(重定向)。
重定向输入让程序使用文件而不是键盘来输入, 重定向输出让程序输出至文件而不是屏幕。
Windows命令行重定向输入
Dome.exe代码
#include<stdio.h>
int main(void){
char ch;
while ((ch = getchar()) != EOF)
putchar(ch);
return 0;
}
<符号是UNIX和DOS/Windows的重定向输入运算符。该运算符使main.c文件与stdin 流相关联,把文件中的内容导入Demo.exe程序。
<两侧的空格是可选的,但有些老旧系统不能有空格(AmigaDOS)
重定向输出
>符号是重定向输出运算符。它创建了一个名为mywords的新文件,然后把Demo.exe的输出重定向至该文件中。 如果已经有一个名为mywords的文件,通常会擦除该文件的内容,然后替换新的内容(但是,许多操作系统有保护现有文件的选项,使其成为只读文件)。
要在每行的末尾单击Enter键,这样才能把缓冲区的内容发送给程序。在下一行的开始处按下Ctrl+D(UNIX)或Ctrl+Z(DOS)即可结束该程序。
组合重定向
Demo.exe < mywords > savewords
Demo.exe > savewords < mywords
在一条命令中,输入文件名和输出文件名不能相同。
在UNIX、Linux 或Windows/DOS系统中使用两个重定向运算符(<和>)时,要遵循以下原则:
- 重定向运算符连接一个可执行程序(包括标准操作系统命令)和一个数据文件,不能用于连接一个数据文件和另一个数据文件,也不能用于连接一个程序和另一个程序。
- 使用重定向运算符不能读取多个文件的输入,也不能把输出定向至多个文件。
UNIX、Linux 或Windows/DOS 还有 >> 运算符,该运算符可以把数据添加到现有文件的末尾,而 | 运算符能把一个文件的输出连接到另一个文件的输入。