APUE——Chapter 5:标准I/O库

2024-05-06 14:58
文章标签 标准 chapter apue

本文主要是介绍APUE——Chapter 5:标准I/O库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

对于标准I/O库,它们的操作则是围绕(stream)进行的。

流的定向(stream’s orientation)决定了所读、写的字符是单字节还是多字节的。

freopen函数清除一个流的定向;fwide函数设置流的定向。

#include <stdio.h>
#include <wchar.h>int fwide(FILE *fp, int mode);/* 返回值:若流是宽定向的则返回正值,若流是字节定向的则返回负值,若流是未定向的则返回0 */

mode为负,字节定向。
mode为正,宽定向。
mode为0,不设置,但返回该流定向的值。

注意,fwide并不改变已定向流的定向。fwide无出错返回。

三个标准I/O流:stdin、stdout、stderr。


5.1 缓冲

标准I/O库提供缓冲的目的是尽可能减少使用read和write调用的次数。

标准I/O库提供了三种类型的缓冲:
(1)全缓冲。在这种情况下,在填满标准I/O缓冲区后才进行实际I/O操作

术语冲洗(flush)说明标准I/O缓冲区的写操作。在标准I/O库方面,flush(冲洗)意味着将缓冲区中的内容写到磁盘上。在终端驱动程序方面,flush(刷清)表示丢弃已存储在缓冲区中的数据。

(2)行缓冲。在这种情况下,当在输入和输出中遇到换行符时,标准I/O库执行I/O操作

行缓冲有两个限制:一,标准I/O库用来收集每一行的缓冲区的长度是固定的,所以只要填满了缓冲区,即使没有写一个换行符,也进行I/O操作。二,任何时候只要通过标准I/O库要求从(a)一个不带缓冲的流,或者(b)一个行缓冲的流(它要求从内核得到数据)得到输入数据,那么就会造成冲洗所有行缓冲输出流。在(b)中带了一个括号中的说明,其理由是,所需的数据可能已在该缓冲区中,它并不要求在需要数据时才从内核读数据。很明显,从不带缓冲的一个流中进行输入((a)项)要求当时从内核得到数据。

常用:标准出错是不带缓冲的;打开至终端设备的流是行缓冲的;其他所有流是全缓冲的。

(3)不带缓冲标准I/O库不对字符进行缓冲存储

更改缓冲类型:

#include <stdio.h>void setbuf(FILE *restrict fp, char *restrict buf);
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);/* 返回值:若成功则返回0, 若出错则返回非0值 */

这些函数一定要在流已被打开后调用。

mode参数:_IOFBF    全缓冲
_IOLBF    行缓冲
_IONBF    不带缓冲

这里写图片描述

如果在一个函数内分配一个自动变量类的标准I/O缓冲区,则从该函数返回之前,必须关闭该流。

#include <stdio.h>int fflush(FILE *fp);/* 返回值:若成功则返回0,若出错则返回EOF */

此函数使该流所有未写的数据都被传送至内核。若fp是NULL,则导致所有输出流被冲洗

5.2 打开流

#include <stdio.h>FILE *fopen(const char *restrict path, const char *restrict type);FILE *freopen(const char *restrict path, const char *restrict type, FILE *restrict fp);FILE *fdopen(int fd, const char *type);/* 返回值:若成功则返回文件指针,若出错则返回NULL */

(1)fopen打开一个指定的文件。
(2)freopen在一个指定的流上打开一个指定的文件,若流已经打开,则先关闭该流。若该流已经定向,则freopen清除该定向。
(3)fdopen获取一个现有的文件描述符,并使一个标准I/O流与该描述符相结合。

这里写图片描述

这里写图片描述

调用fclose关闭一个打开的流:

#include <stdio.h>int fclose(FILE *fp);/* 返回值:若成功则返回0,若出错则返回EOF */

文件被关闭之前,冲洗缓冲区中的输出数据。丢弃缓冲区中的任何输入数据。如果标准I/O库已经为该流自动分配了一个缓冲区,则释放此缓冲区。

当一个进程正常终止时(直接调用exit函数,或者从main函数返回),则所有未写缓冲数据的标准I/O流都会被冲洗,所有打开的标准I/O流都会被关闭。

5.3 读、写流

(1)每次一个字符的I/O。
(2)每次一行的I/O。fgets和fputs。
(3)直接I/O。fread和fwrite。

#include <stdio.h>int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);/* 返回值:若成功则返回下一个字符,若已达到文件结尾或者出错则返回EOF */int ferror(FILE *fp);
int feof(FILE *fp);/* 返回值:若条件为真则返回非0值,否则返回0 */void clearerr(FILE *fp);int ungetc(int c, FILE *fp);/* 返回值:若成功则返回c,若出错则返回EOF */int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);/* 返回值:若成功则返回c,若出错则返回EOF */

在多数实现中,为每个流在FILE对象中维持了两个标志:

  • 出错标志
  • 文件结束标志

调用clearerr则清除这两个标志。

从流中读取数据以后,可以调用ungetc将字符再压送回流中。

#include <stdio.h>char *fgets(char *restrict buf, int n, FILE *restrict fp);
char *gets(char *buf);/* 返回值:若成功则返回buf,若已到达文件结尾或出错则返回BULL */char *fputs(const char *restrict str, FILE *restrict fp);
char *puts(const char *str);/* 返回值:若成功则返回非负值,若出错则返回EOF */

请使用fgets。原因:一、gets不能指定缓冲区的长度,可能造成缓冲区溢出。二、gets并不将换行符存入缓冲区中。

#include <stdio.h>size_t fread(void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);
size_t fwrite(const void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);/* 返回值:读或写的对象数 */

5.4 定位流

#include <stdio.h>long ftell(FILE *fp);/* 返回值:若成功则返回当前文件位置指示,若出错则返回-1L */int fseek(FILE *fp, long offset, int whence);/*  SEEK_SET、SEEK_CUR、SEEK_END返回值:若成功则返回0,若出错则返回非0值 */void rewind(FILE *fp);off_t ftello(FILE *fp);/* 返回值:若成功则返回当前文件位置指示,若出错则返回-1 */
int fseeko(FILE *fp, off_t offset, int whence);/* 返回值:若成功则返回0,若出错则返回非0值 */int fgetpos(FILE *restrict fp, fpos_t *restrict pos);
int fsetpos(FILE *fp, const fpos_t *pos);/* 返回值:若成功则返回0,若出错则返回非0值 */

5.5 格式化I/O

#include <stdio.h>int printf(const char *restrict format, ...);
int fprintf(FILE *restrict fp, const char *restrict format, ...);/* 返回值:若成功则返回输出字符数,若出错则返回负值 */int sprintf(char *restrict buf, const char *restrict format, ...);
int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);/* 返回值:若成功则返回存入数组的字符数,若出错则返回负值 */

转换说明:

%[flags][fldwidth][precision][lenmodifier]convtype

flags:
这里写图片描述

fldwidth说明转换的最小字段宽度。

precision说明整型转换后最少输出数字位数、浮点数转换后小数点后的最少位数。

lenmodifier说明参数长度:
这里写图片描述

convtype:
这里写图片描述

#include <stdio.h>
#include <stdarg.h>int vprintf(const char *restrict format, va_list arg);
int vfprintf(FILE *restrict fp, const char *restrict format, va_list arg);/* 返回值:若成功则返回输出字符数,若出错则返回负值 */int vsprintf(char *restrict buf, const char *restrict format, va_list arg);
int vsnprintf(char *restrict buf, size_t n, const char *restrict format, va_list arg);/* 返回值:若成功则返回存入数组的字符数,若出错则返回负值 */
#include <stdio.h>int scanf(const char *restrict format, ...);
int fscanf(FILE *restrict fp, const char *restrict format, ...);
int sscanf(const char *restrict buf, const char *restrict format, ...);/* 返回值:指定的输入项数;若出错或在任意变换前以到达文件结尾则返回EOF */

转换说明:

%[*][fldwidth][lenmodifier]convtype

可选的(*)用于抑制转换。

fldwidth说明最大宽度。

lenmodifier说明要用转换结果初始化的参数大小。

convtype:
这里写图片描述

#include <stdarg.h>
#include <stdio.h>int vscanf(const char *restrict format, va_list arg);
int vfscanf(FILE *restrict fp, const char *restrict format, va_list arg);
int vsscanf(const char *restrict buf, const char *restrict format, va_list arg);/* 返回值:指定的输入项数;若出错或在任意变换前以到达文件结尾则返回EOF */

5.6 其他

每一个标准I/O流都有一个与其相关联的文件描述符。用fileno函数获取其描述符。

#include <stdio.h>int fileno(FILE *fp);/* 返回值:与该流相关联的文件描述符 */

创建临时文件:

#include <stdio.h>char *tmpnam(char *ptr);/* 返回值:指向唯一路径名的指针 */FILE *tmpfile(void);/* 返回值:若成功则返回文件指针,若出错则返回NULL */char *tempnam(const char *directory, const char *prefix);/* 返回值:指向唯一路径名的指针 */#include <stdlib.h>
int mkstemp(char *template);/* 返回值:若成功则返回文件描述符,若出错则返回-1 */
  • mkstemp创建的临时文件不会自动删除。我们需要自行unlink它。
  • tmpnam和tempnam的不足之处:在返回唯一路径名和应用程序用该路径名创建文件之间有一个时间窗口。在该时间窗口期间,另一个进程可能创建一个同名文件。tmpfile和mkstemp则不会

最后,标准I/O的替代库:

sfio、mmap函数、uClibc C库、newlibc C库

这篇关于APUE——Chapter 5:标准I/O库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/964658

相关文章

数据治理框架-ISO数据治理标准

引言 "数据治理"并不是一个新的概念,国内外有很多组织专注于数据治理理论和实践的研究。目前国际上,主要的数据治理框架有ISO数据治理标准、GDI数据治理框架、DAMA数据治理管理框架等。 ISO数据治理标准 改标准阐述了数据治理的标准、基本原则和数据治理模型,是一套完整的数据治理方法论。 ISO/IEC 38505标准的数据治理方法论的核心内容如下: 数据治理的目标:促进组织高效、合理地

C 标准库 - `<float.h>`

C 标准库 - <float.h> 概述 <float.h> 是 C 标准库中的一个头文件,它定义了与浮点数类型相关的宏。这些宏提供了关于浮点数的属性信息,如精度、最小和最大值、以及舍入误差等。这个头文件对于需要精确控制浮点数行为的程序非常有用,尤其是在数值计算和科学计算领域。 主要宏 <float.h> 中定义了许多宏,下面列举了一些主要的宏: FLT_RADIX:定义了浮点数的基数。

《C++标准库》读书笔记/第一天(C++新特性(1))

C++11新特性(1) 以auto完成类型自动推导 auto i=42; //以auto声明的变量,其类型会根据其初值被自动推倒出来,因此一定需要一个初始化操作; static auto a=0.19;//可以用额外限定符修饰 vector<string> v;  auto pos=v.begin();//如果类型很长或类型表达式复杂 auto很有用; auto l=[] (int

Chapter 13 普通组件的注册使用

欢迎大家订阅【Vue2+Vue3】入门到实践 专栏,开启你的 Vue 学习之旅! 文章目录 前言一、组件创建二、局部注册三、全局注册 前言 在 Vue.js 中,组件是构建应用程序的基本单元。本章详细讲解了注册和使用 Vue 的普通组件的两种方式:局部注册和全局注册。 本篇文章参考黑马程序员 一、组件创建 ①定义 Vue 组件是一种具有特定功能的 Vue 实

Chapter 10 Stability and Frequency Compensation

Chapter 10 Stability and Frequency Compensation Chapter 8介绍了负反馈, 这一章介绍稳定性, 如果设计不好, 负反馈系统是要发生震荡的. 首先我们学习理解稳定判断标准和条件, 然后学习频率补偿, 介绍适用于不同运放的补偿方式, 同时介绍不同补偿对两级运放slew rate的影响, 最后介绍Nyquist’s判断标准 10.1 Gener

标准IO与系统IO

概念区别 标准IO:(libc提供) fopen fread fwrite 系统IO:(linux系统提供) open read write 操作效率 因为内存与磁盘的执行效率不同 系统IO: 把数据从内存直接写到磁盘上 标准IO: 数据写到缓存,再刷写到磁盘上

通信工程学习:什么是AM标准调幅

AM标准调幅       AM标准调幅,即Amplitude Modulation(振幅调制),是一种在电子通信中广泛使用的调制方法,特别是在无线电载波传输信息方面。以下是关于AM标准调幅的详细解释: 一、AM标准调幅的定义与原理 AM标准调幅的定义:        AM调幅是通过改变载波信号的振幅(即信号强度或电压幅度),使其与信息信号(如音频、视频等)同步变化,从而实现信息的传

【电子通识】洁净度等级划分及等级标准

洁净度常用于评估半导体、生物制药、医疗、实验室及科研院所、新能源等领域的洁净室、无尘室或者无菌室等环境。         一般来说,晶圆光刻、制造、测试等级为100级或1000级的洁净间,百级洁净间要求空气中0.5微米的尘埃粒子数不得超过每立方米3520个;等级为1000级的洁净间要求0.5微米的尘埃粒子数不得超过每立方米35200个。         晶圆切割或封装工序一

标准库标头 <filesystem> (C++17)学习

此头文件是文件系统支持库的一部分。本篇介绍filesystem命名空间的一些函数。 函数 在命名空间 std::filesystem 定义 absolute (C++17) 组成一个绝对路径 (函数) canonicalweakly_canonical (C++17) 组成一个规范路径 (函数) relativeproximate (C++17) 组成一个相对路径 (函数) copy (C

搭建服务器机房的标准是什么?

企业在进行选择服务器时,可能会将服务器放置公司,但是大多数企业还是会选择服务器租用或托管服务,因为专业的IDC服务商通常能够提供良好的机房环境来进行放置服务器,接下来小编就主要来介绍一下搭建服务器机房的标准都有哪些吧! 首先对于机房的位置选择要保证原理水源、油库和化工厂等危险的场所,并且不应该建设在容易受到水灾和地震等自然灾害影响的地区当中,防止出现不可遏制的情况发生,造成重大的经济损失。