1. 单字符I/O:getchar()和putchar()
ANSI C标准发布后,C把stdio.h头文件与使用getchar()和putchar()相关联。
getchar()和putchar()都不是真正的函数,它们被定义为供预处理器使用的宏。
2. 缓冲区
无缓冲输入,即程序可立即使用输入的字符。在按下enter键之前,用户输入的字符都会被存储在被称为“缓冲区”的临时存储区域,按下enter键后,程序才可使用用户输入的字符,这种形式的叫缓冲输入。
3. 结束键盘输入
如果在字符中选择一个作为结束标记,那么就无法再文本中使用该字符,因为程序读到该字符时就会停止读取了。
那能不能选择一个无法正常输入的字符来作为结束标记呢?C确实提供了这样的字符,不过在这之前,先了解一下C处理文件的方式。
3.1 文件、流和键盘输入
文件是储存器中储存信息的区域,通常保存在某种永久存储器中。C有许多用于打开、读取、写入和关闭文件的函数。
直接调用操作系统的函数被称为底层I/O(low-level I/O)。因为计算机系统不同,所以没有底层I/O函数的标准库,但是在较高层次上面,C通过标准I/O包(standard I/O package)来到处理文件。
从概念上看,C程序处理的是流而不是直接处理文件,流(stream)是一个实际输入或输出映射的理想化数据流。不同属性和不同种类的输入,由属性更统一的流来表示。打开文件就是将流与文件相关联,读写是通过流来完成。
3.2 文件结尾
计算机操作系统要以某种方式判断文件的开始和结束。
检测文件结束的一种方法是在文件末尾添加一个特殊字符。常见的在文件末尾添加Ctrl+Z。现代文本文件的末尾不一定有Ctrl+Z,但如果有,则操作系统会将其视为文件末尾。
另一种检测文件结束的方法是储存文件大小,例如文件有3000字节大小,那么程序会在读取3000个字节后停止读取。
在C语言中,使用getchar()读取到文件末尾时会返回一个特殊的值EOF(end of fille)。scanf()函数检测到文件末尾时也返回EOF。通常EOF定义在stdio.h文件中。#define EOF (-1)
为什么是-1?
getchar()函数的返回值通常介于0~127,这些值对应标准字符集。如果使用扩展字符集,则返回值介于0~255之间。无论什么情况,-1都不对应任何字符。
4. 重定向和文件
在默认情况下,C程序使用标准I/O包查找标准输入作为输入源。具体的标准输入因平台而定,它可能是磁带、穿孔卡,但更多的是键盘输入。
如果想要使用文件,第1种方法是显式使用函数打开文件、关闭文件、读取文件、写入文件。第2种方法是设计能与键盘和屏幕交互的程序,同庚哦不同的渠道重定向输入至文件和从文件输出。
重定向的规则与系统有关,与C无关,一些C实现还在缺乏重定向特性的系统中模拟它。
4.1 UNIX、Linux和DOS重定向
4.1.1 重定向输入
假设有一个可执行程序(main.exe),它的功能是将读取的输入打印在屏幕上。
// main.exe
#include <stdio.h>
int main() {
char ch;
while ((ch = getchar()) != EOF) {
putchar(ch);
}
return 0;
}
在终端输入命令main.exe < input.txt,就能将input.txt文件中的文本输入到程序中。
<是UNIX和DOS/Window的重定向运算符。
4.1.2 重定向输出
如果要将main.exe文件的输入写入output.txt文件中,需要使用main.exe > output.txt。(无需要提前创建output.txt文件,当文件不存在时,会自动创建对应文件)。
⚠️注意:如果output.txt文件内存在内容,那么程序输出时,会将文件内容清空后再写入。