C和指针 第15章 输入/输出函数 15.4 ANSI I/O概念

本文详细介绍了C语言中的ANSI I/O概念,包括流、文本流与二进制流的区别,以及文件和标准I/O常量的相关知识。流是C程序中进行I/O操作的基础,分为文本流和二进制流,各有其特点。stdio.h头文件提供了与流相关的函数。标准I/O常量如EOF和FOPEN_MAX在程序中起到关键作用。同时,文章强调了缓冲区在I/O操作中的作用,以及在调试时如何处理缓冲输出的问题。
摘要由CSDN通过智能技术生成

15.4 ANSI I/O概念
    头文件stdio.h包含了与ANSI函数库的I/O部分有关的声明。它的名字来源于旧式的标准I/O函数库。尽管不包含这个头文件也可以使用某些I/O函数,但绝大多数I/O函数在使用前都需要包含这个头文件。
    15.4.1 流
    当前的计算机具有大量不同的设备,很多都与I/O操作有关。CD-ROM驱动器、软盘和硬盘驱动器、网络连接,通信端口和视频适配器就是这类很常见的设备。每种设备具有不同的特性和操作协议。操作系统负责这些不同设备的通信细节,并向程序提供一个更为简单和统一的I/O接口。
    ANSI C进一步对I/O的概念进行了抽象。就C程序而言,所有的I/O操作只是简单地从程序移进或移出字节。因此,好不惊奇的是,这种字节便被称为流(stream)。程序只需要关心创建正确的输出字节数据,以及正确地解释从输入读取的字节数据。特定I/O设备的细节对程序员是隐藏的。
    绝大多数流是完全缓冲的(fully buffered),这意味着“读取”和“写入”实际上是从一块称为缓冲区(buffer)的内存区域来回复制数据。从内存中来回复制数据是非常快速的。用于输出流的缓冲区只有被写满时才会刷新(flush,物理写入)到设备或文件中。把写满的缓冲区一次性写入相较于逐片把程序产生的输入分别写入,其效率更高。类似地,输入缓冲区为空时会通过从设备或文件读取下一块较大的输入,重新填满缓冲区。
    使用标准输入和输出时,这种缓冲可能会引起混淆。所以,只有当操作系统可以断定它们与交互设备并无联系时,才会进行完全缓冲。否则,它们的缓冲状态将因编译器而异。一个常见(但并不普遍)的策略是把标准输出和标准输入联系在一起,就是当请求输入时同时刷新缓冲区。这样,在用户必须进行输入之前,提示用户进行输入的信息和以前写入到缓冲区中的内容将出现在屏幕上。
    警告:
    尽管这种缓冲通常是我们需要的,但在调试程序时仍可能引起混淆。一种常见的调试策略是把一些printf函数的调用散布于程序中,确定错误出现的具体位置。但是,这些函数调用的输出结果被写入到缓冲区中,并不立即显示到屏幕上。事实上,如果程序失败,缓冲输出可能不会被实际写入,这就可能使程序员无法得到错误出现的正确位置。这个问题的解决方法就是在每个用于调试的
printf函数之后立即调用fflush,如下所示:
    printf( "something or other" );
    fflush( stdout );
    fflush迫使缓冲区的数据立即写入,不管它是否已满。
    1.文本流
    流分为两种类型:文本(text)流和二进制(binary)流。文本流的有些特性在不同的系统中可能不同,其中之一就是文本行的最大长度。标准规定至少允许254个字符。另一个可能不同的特性就是文本行的结束方式。例如,在MS-DOS系统中,文本文件约定以一个回车符和一个换行符(或称为行反馈符)结尾。但是UNIX系统只使用一个换行符结尾。
    提示:
    标准把文本行定义为零个或多个字符,后面跟一个表示结束的换行符。对于那些文本行的外在表现形式与这个定义不同的系统上,库函数负责外部形式和内部形式之间的翻译。例如,在MS-DOS系统中,在输出时,文本中的换行符被写成一对回车/换行符。在输入时,文本中的回车符被丢弃。这种不必考虑文本的外部形式而操纵文本的能力简化了可移植性程序的创建。
    2.二进制流
    二进制流中的字节将完全根据程序编写它们的形式写入到文件或设备中,而且完全根据它们从文件或设备读取的形式读入到程序中。它们并未做任何改变。这种类型的流适用于非文本数据。如果不希望I/O函数修改文件的行末字符,也可以把它用于文本文件。
    15.4.2 文件
    stdio.h所包含的声明之一就是FILE结构。请不要把它和存储于磁盘上的数据文件相混淆。FILE是一个数据结构,用于访问一个流。如果同时激活了几个流,每个流都有一个相应的FILE与它联系。为了在流上执行一些操作,需要调用一些合适的函数,并向它们传递一个与这个流关联的FILE参数。
    对于每个ANSI C程序,运行时系统必须提供至少3个流---标准输入(standard input)、标准输出(standard output)和标准错误(standard error)。这些流的名字分别是stdin、stdout和stderr,它们都是一个指向FILE结构的指针。标准输入是缺省情况下输入的来源,标准输出是缺省的输出设备。具体的缺省值因编译器而异,通常标准输入为键盘设备,标准输出为终端或屏幕。
    许多操作系统允许用户在程序执行时修改缺省的标准输入和输出设备。例如,MS-DOS和UNIX系统都支持用下面这种方法进行输入/输出重定向:
    $ program < data > answer
    当执行这个程序时,它会将data(而不是键盘)作为标准输入进行读取,而且将把标准输出写入到文件answer中(而不是屏幕上)。有关I/O重定向的细节,请查阅你的系统文档。
    标准错误就是写入错误信息的地方。perror函数把它的输出也写到这个地方。在许多系统中,标准输出和标准错误在缺省情况下是相同的。但是,为错误信息准备一个不同的流意味着,即使标准输出重定向到其他地方,错误信息仍将出现在屏幕或其他缺省的输出设备上。
    15.4.3 标准I/O常量
    stdio.h中定义了数量众多的与输入和输出有关的常量。EOF是许多函数的返回值,它提示到达了文件尾。EOF所选择的实际值比一个字符要多几位,这是为了避免二进制值被错误地解释为EOF。
    一个程序同时最多打开多少个文件呢?它和编译器有关,但可以保证至少能同时打开FOPEN_MAX个文件。常量FOPEN_MAX包括了3个标准流,它的值至少是8。
    常量FILENAME_MAX是一个整型值,用于提示一个字符数组应该多大,以便容纳编译器所支持的最长合法文件名。如果对文件名的长度没有一个实际的限制,则这个常量的值就是文件名的推荐最大长度。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_40186813

你的能量无可限量。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值