APUE学习笔记(第五章 标准I/O)

本章讲述标准I/O库

流和FILE对象

对于标准I/O库,它们的操作是围绕流进行的。流的定向决定了所读、写的字符是单字节还是多字节的。

#include <stdio.h>
#include <wchar.h>
int fwide(FILE *fp,int mode);

fwide函数可用于流的定向。根据mode参数的不同值,fwide函数执行不同的工作

若mode参数值为负,fwide将试图使指定的流是字节定向的

若mode参数值为正,fwide将试图使指定的流是宽定向的

若mode参数值是0,fwide将不试图设置流的定向,但返回标志该流定向的值

当一个流最初被创建时,它并没有定向。若在未定向的流上使用一个多字节(单字节)I/O函数,则将该流设置为宽(字节)定向。fwide并不改变已定向流的定向。

标准输入、标准输出和标准错误

对一个进程预定义了3个流:stdin、stdout、stderr。

缓冲

标准I/O提供了以下3种类型的缓冲

1 全缓冲,在这种情况下,在填满标准I/O缓冲区后才进行实际I/O操作。如磁盘上的文件通常实施全缓冲。

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

3 不带缓冲,标准I/O库不对字符进行缓冲存储。标准错误流stderr通常是不带缓冲的。

我们可以调用下面两个函数更改缓冲类型

#include <stdio.h>
void setbuf(FILE *restrict fp,char *restrict buf);
int setvbuf(FILE *restrict fp,char *buf,int mode,size_t size);

可以使用setbuf打开或关闭缓冲机制,参数buf指定一个长度为BUFSIZ的缓冲区。将buf设置为NULL可以关闭缓冲。

使用setvbuf,我们可以精确地说明所需的缓冲类型。这是用mode参数实现的:

_IOFBF  全缓冲

_IOLBF  行缓冲

_IONBF  不带缓冲

我们可以通过fflush函数冲洗一个流

#include <stdio.h>
int fflush(FILE *fp);

打开流

下面3个函数打开一个标准I/O流

#include <stdio.h>
FILE *fopen(const char *restrict pathname,const char *restrict type);
FILE *freopen(const char *restrict pathname,const char *restrict type,FILE *restrict fp);
FILE *fdopen(int fd,const char *type);

type参数指定对该I/O流的读、写方式,ISO C规定type参数可以有如下15种不同的值

其中b作为type的一部分,这使得标准I/O系统可以区分文本文件和二进制文件

调用fclose关闭一个打开的流

#include <stdio.h>
int fclose(FILE *fp);

读和写流

以下3个函数可用于一次读一个字符

#include <stdio.h>
int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);   //等同于getc(stdin)

对应上面所述的每个输入函数都有一个输出函数

#include <stdio.h>
int putc(int c,FILE *fp);
int fputc(int c,FILE *fp);
int putchar(int c);

每次一行I/O

下面两个函数提供每次输入一行的功能

#include <stdio.h>
char *fgets(char *restrict buf,int n,FILE *restrict fp); //buf为缓冲区地址,读入的行将送入其中,参数n指定缓冲的长度
char *gets(char *buf);  //不推荐使用

fputs和puts提供每次输出一行的功能

#include <stdio.h>
int fputs(const char *restrict str,FILE *restrict fp);
int puts(const char *str);

二进制I/O

下列两个函数执行二进制I/O操作

#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);

参数size为欲写结构的长度,nobj为欲写的元素个数,函数返回的是读或写的对象数。这些函数有以下两种常见的用法

float data[10];
if(fwrite(&data[2],sizeof(float),4,fp)!=4)
    err_sys("fwrite error");
//读写一个结构
struct{
      short count;
      long total;
      char name[NAMESIZE];
}item;

if(fwrite(&item,sizeof(item),1,fp)!=1)
     err_sys("fwrite error");

定位流

有3种方法定位标准I/O流

#include <stdio.h>
long ftell(FILE *fp);   //若成功,则返回当前文件位置指示,出错则返回-lL
int fseek(FILE *fp,long offset,int whence);
void rewind(FILE *fp);

除了偏移量的类型是off_t而非long以外,ftello函数与ftell相同,fseeko函数与fseek相同

#include <stdio.h>
off_t ftello(FILE *fp);
int fseeko(FILE *fp,off_t offset,int whence);

下面函数是ISO C标准引入的

#include <stdio.h>
int fgetpos(FILE *restrict fp,fpos_t *restrict pos);
int fsetpos(FILE *fp,const fpos_t *pos);

格式化I/O

格式化输出是由printf函数处理的

#include <stdio.h>
int printf(const char *restrict format,...);
int fprintf(FILE *restrict fp,const char *restrict format,...);
int dprintf(int fd,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,...);    //参数n指定缓冲区长度

执行格式化输入处理的是3个scanf函数

#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,...);

临时文件

ISO C标准I/O库提供了两个函数以帮助创建临时文件

#include <stdio.h>
char *tmpnam(char *ptr);
FILE *tmpfile(void);

tmpnam函数产生一个与现有文件名不同的一个有效路径名字符串

tmpfile创建一个临时二进制文件(类型wb+),在关闭该文件或程序结束时将自动删除。

时间: 2024-10-06 19:54:12

APUE学习笔记(第五章 标准I/O)的相关文章

APUE读书笔记-第五章 标准I/O库

今天草草的把第四章结了,后面的内容分析的也不是很详细,就连书中的例子都没有怎么实验,还是等以后有机会吧. 从5.3节开始研究起吧,这一节主要谈了一个进程预定义的3个流,分别是标准输入.标准输出和标准错误,通过stdin.stdout.stderr引用.这里要和进程中的文件描述符STDIN_FILENO.STDOUT_FILENO.STDERR_FILENO相区分. /* Standard streams. */ extern struct _IO_FILE *stdin; /* Standard

APUE学习笔记:第九章 进程关系

9.1 引言 本章将更详尽地说明进程组以及POSIX.1引入的会话的概念.还将介绍登陆shell(登录时所调用的)和所有从登陆shell启动的进程之间的关系. 9.1 终端登陆 系统管理员创建通常名为/etc/ttys的文件,其中每个终端设备都有一行,每一行说明设备名传递给getty程序的参数.当系统自举时,内核创建进程ID为1的进程,依旧是init进程.init进程使系统进入多用户状态.init进程读文件/etc/ttys,对每一个允许登陆的终端设备,init调用一次fork,所生成的子进程则

APUE学习笔记:第一章 UNUX基础知识

1.2 UNIX体系结构 从严格意义上,可将操作系统定义为一种软件(内核),它控制计算机硬件资源,提供程序运行环境.内核的接口被称为系统调用.公用函数库构建在系统调用接口之上,应用软件即可使用公用函数库,也可使用系统调用.shell是一种特殊的应用程序,它为运行其他应用程序提供了一个接口 从广义上,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并给予计算机以独有的特性(软件包括系统实用程序,应用软件,shell以及公用函数库等) 1.3  shell shell是一个命令行解

APUE学习笔记:第二章 UNIX标准化及实现

2.2UNIX标准化 2.2.1 ISO C 国际标准化组织(International Organization for Standardization,ISO) 国际电子技术委员会(International Electrotechnical Commission,IEC) ISO C标准的意图是提供C程序的可移植性,使其能适合于大量不同的操作系统,而不只是UNIX系统.此标准不仅定义了C程序设计语言的语法和语义,还定义了其标准库.因为所有现今的UNIX系统都提供C标准中定义的库例程,所以该

《Spring实战》学习笔记-第五章:构建Spring web应用

之前一直在看<Spring实战>第三版,看到第五章时发现很多东西已经过时被废弃了,于是现在开始读<Spring实战>第四版了,章节安排与之前不同了,里面应用的应该是最新的技术. 本章中,将会接触到Spring MVC基础,以及如何编写控制器来处理web请求,如何通明地绑定请求参数到业务对象上,同时还可以提供数据校验和错误处理的功能. Spring MVC初探 跟踪Spring MVC请求 在请求离开浏览器时,会带有用户所请求内容的信息,例如请求的URL.用户提交的表单信息. 请求旅

Java学习笔记—第五章

第五章  Java运算符和表达式 定义:运算符是指具有运算功能的符号.参与运算的数据称为操作数.运算符和操作数按照一定的规则组成的式子称为表达式. 运算符的分类: 根据操作数个数不同分类:单目运算符(一元运算符).双目运算符(二元运算符).三目运算符(三元运算符) 根据性质或用途不同分类:算术运算符(+.-.*./.%.++.--).关系运算符(>.<.>=.<=.= =.!=).逻辑运算符(!.&&.||).位运算符(>>.<<.>&

javascript高级程序设计 学习笔记 第五章 上

第五章 引用类型的值(对象)是引用类型的一个实例.在 ECMAScript 中,引用类型是一种数据结构, 用于将数据和功能组织在一起.它也常被称为类,但这种称呼并不妥当.尽管 ECMAScript 从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构.引用类型有时候也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法. 对象是某个特定引用类型的实例.新对象是使用 new 操作符后跟一个构造函数来创建的. 构造函数本身就是一个函数,只不过该函数是出于创建新

Android学习笔记—第五章 进程与线程

第五章 进程与线程 进程:一个应用程序就是一个进程 (1)进程的优先级: Foreground Process 前台进程 a. 当前用户正在操作的Activity所在的进程 b. 绑定了当前用户操作的Activity的service所在的进程 c. 通过调用了startForeground()方法提升优先级的service所在的进程 d. 正在调用onCreate().onStart().onDestory()方法的service所在的进程 e. 正在调用onReceiver()方法的Broad

JavaScript高级程序设计学习笔记第五章--引用类型(函数部分)

四.Function类型: 1.函数定义的方法: 函数声明:function sum (num1, num2) {return num1 + num2;} 函数表达式:var sum = function(num1, num2){return num1 + num2;};//注意有个分号 构造函数的方式:var sum = new Function("num1", "num2", "return num1 + num2");// 2.函数的重复声

《DOM Scripting》学习笔记-——第五章、第六章 案列改进

第四章的案例代码可以得到更好的改进.例如:预留退路.向后兼容性和分离js. 原html代码: 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 </head> 7 <body> 8 <h1>Snapshots<