7 输入与输出
输入/输出功能并不是 C 语言本身的组成部分,所以到目前为止,我们并没有过多地强调
但是,程序与环境之间的交互比我们在前面部分中描述的情况要复杂很多
本章将讲述标准库,介绍一些输入/输出函数、字符串处理函数、存储管理函数与数学函数,以及其它一些 C 语言程序的功能
本章讨论的重点将放在输入/输出上
ANSI 标准精确地定义了这些库函数,所以,在任何可以使用 C 语言的系统中都有这些函数的兼容形式
如果程序的系统交互部分仅仅使用了标准库提供的功能,则可以不经修改地从一个系统移植到另一个系统中
这些库函数的属性分别在十多个头文件中声明,前面已经遇到过一部分,如 <stdio.h>
、<string.h>
和 <ctype.h>
附录 B 对标准库进行了详细的描述
7.1 标准输入/输出
在第 1 章中讲过,标准库实现了简单的文本输入/输出模式
文本流由一系列行组成,每一行的结尾是一个换行符
如果系统没有遵循这种模式,则标准库将通过一些措施使得该系统适应这种模式
例如,标准库可以在输入端将回车符和换行符都转换为换行符,而在输出端进行反向转换
最简单的输入机制是使用 getchar
函数从标准输入中(一般为键盘)一次读取一个字符:int getchar(void)
getchar
函数在每次被调用时返回下一个输入字符,若遇到文件结尾,则返回 EOF
符号常量 EOF
在头文件 <stdio.h>
中定义,其值一般为 -1
程序中应该使用 EOF
来测试文件是否结束,这样才能保证程序同 EOF
的特定值无关
在许多环境中,可以使用符号 <
来实现输入重定向,它将把键盘输入替换为文件输入
如果程序 prog
中使用了函数 getchar
,则命令行 prog <infile
将使得程序 prog
从输入文件 infile
(而不是从键盘)中读取字符
实际上,程序 prog
本身并不在意输入方式的改变,并且,字符串 "<infile"
也并不包含在 argv
的命令行参数中
如果输入通过管道机制来自于另一个程序,那么这种输入切换也是不可见的
比如,在某些系统中,命令行 otherprog | prog
将运行两个程序 otherprog
和 prog
并将程序 otherprog
的标准输出通过管道重定向到程序 prog
的标准输入上
函数 int putchar(int)
用于输出数据
putchar(c)
将字符 c
送至标准输出上,在默认情况下,标准输出为屏幕显示
如果没有发生错误,则函数 putchar
将返同输出的字符,如果发生了错误,则返回 EOF
同样,通常情况下,也可以使用 > 输出文件名
的格式将输出重定向到某个文件中
例如,如果程序 prog
调用了函数 putchar
那么命令行 prog > 输出文件名
将把程序 prog
的输出从标准输出设备重定向到文件中
如果系统支持管道,那么命令行 prog | anotherprog
将把程序 prog
的输出从标准输出通过管道重定向到程序 anotherprog
的标准输入中
函数 printf
也向标准输出设备上输出数据
我们在程序中可以交叉调用函数 putchar
和 printf
,输出将按照函数调用的先后顺序依次产生
使用输入/输出库函数的每个源程序文件必须在引用这些函数之前包含语句 #include <stdio.h>
当文件名用一对尖括号 <
和 >
括起来时,预处理器将在由具体实现定义的有关位置中查找指定的文件
例如在 UNIX 系统中,文件一般放在目录 /usr/include
中
许多程序只从一个输入流中读取数据,并且只向一个输出流中输出数据
对于这样的程序,只需要使用函数 getchar
、putchar
和 printf
实现输入/输出即可,并且对程序来说已经足够了
特别是,如果通过重定向将一个程序的输出连接到另一个程序的输入,仅仅使用这些函数就足够了
例如,考虑下列程序 lower
,它用于将输入转换为小写字母的形式:
#include <stdio.h>
#include <ctype.h>
main() /* lower: convert input to lower case*/
{
int c
while ((c = getchar()) != EOF)
putchar(tolower(c));
return 0;
}
函数 tolower
在头文件 <ctype.h>
中定义,它把大写字母转换为小写形式,并把其它字符原样返回
我们在前面提到过,头文件 <stdio.h>
中的 getchar
和 putchar
“ 函数 ” 以及 <ctype.h>
中的 tolower
“ 函数 ” 一般都是宏
这样就避免了对每个字符都进行函数调用的开销,我们将在 8.5 节介绍它们的实现方法
无论 <ctype.h>
中的函数在给定的机器上是如何实现的,使用这些函数的程序都不必了解字符集的知识