标准I/O库处理很多细节,使得便于用户使用。

流和 FILE 对象

对于标准I/O库,操作是围绕 流(stream)进行的。当用标准I/O打开或创建一个文件时,我们已使一个流与一个文件相关联。

对于ASCII字符集,一个字符用一个字节表示。对于国际字符集,一个字符可用多个字节表示。流的定向决定所读,写的字符是单字节还是多字节。

一个流在创建的最初,并没有定向,如果对未定向的流使用多字节I/O函数,则将该流定向为款定向的,反之如果使用单字节I/O函数,则将流的定向设为字节定向的。

改变流的定向的函数(只有两个):

freopen : 清楚一个流的定向

fwide        :   设置流的定向

int fwide ( FILE *fp , int mode );

宽定向返回正值,字节定向返回负值,未定向的返回0;

  • 如果mode参数为负 , fwide试图使指定的流是字节定向
  • 如果mode参数为正 , fwide试图使指定的流是宽定向的
  • 如果mode参数为 0  , fwide将不试图设置流的定向,但返回标识该流定向的值。

fwide 并不改变已定向流的定向。

标准输入 , 标准输出 , 标准错误。

文件描述符 分别为 STDIN_FILENO , STDOUT_FILENO , STDERR_FILENO

通过预定文件指针 stdin , stdout , stderr。这三个文件指针分别在头文件<stdio.h>中

缓冲

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

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

全缓冲:在填满标准I/O缓冲区后才进行实际I/O操作。

行缓冲:在输入和输出遇到换行符时,标准I/O库执行I/O操作。

不缓冲:比如strerr,这样使得出错信息可以尽快显示出来。

对任何一个给定的流,可以调用下列两个函数中的一个更改缓冲类型。

void setbuf ( FILE *restrict fp , char *restrict buf ) ;

int setvbuf ( FILE *restrict fp , char *restrict buf , int mode , size_t size );

使用 setbuf 函数打开或关闭缓冲机制。为了带缓冲进行I/O,参数buf指向一个长度为BUFSIZE的缓冲区,为了关闭缓冲,将buf设置为NULL。

使用 setvbuf , 可以精确的说明所需缓冲类型。 mode 参数:

_IOFBF     全缓冲

_IOLBF     行缓冲

_IONBF    不缓冲

147页有图。

打开流

下列三个函数打开一个标准I/O流。

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

区别在于:

  1. fopen打开一个路径名为pathname的一个指定文件
  2. freopen在一个指定的流上打开一个指定的文件 。
  3. fdopen取一个文件描述符,并使一个标准的I/O流与该描述符结合。

type有15种不同的值 —— 图5.2

读和写流

输入函数:

以下三个函数可以一次读一个字符

int getc ( FILE *fp )

int fgetc (FILE *fp )

int getchar ( void )

getchar 等同于 getc(stdin)。

getc可被实现为宏,fgetc不能实现为宏。

  1. getc的参数不应当是具有副作用的表达式
  2. fgetc一定是一个函数,所以可以得到其地址。
  3. 调用fgetc的时间可能比getc的时间长。

由于不管出错还是达到文件尾端。三个函数都是返回同样的值。为了区分,调用ferror 或 feof

int ferror ( FILE *fp )

int feof ( FILE *fp )

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

出错标志

文件结束标志

输出函数:

int putc ( int c , FILE *fp )

int fputc ( int c , FILE *fp )

int putchar ( int c )

putchar( C ) 等同于 putc ( c , stdout ) ,  putc 可被实现为宏 , 而fputc不能实现为宏。

每次一行 I/O

char *fgets ( char *restrict buf , int n , FILE *restrict fp )

char *gets ( char *buf )

gets从标准输入读, fgets 从指定的流读。

对于 fgets , 必须指定缓冲的长度为 n 。 此函数一直读到下一个换行符为止。

gets是一个不推荐使用的函数,因为不能指定在使用gets时缓冲区的长度。可能造成缓冲区溢出。

gets并不将换行符存入缓冲区

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

int fputs ( const char *restrict str , FILE *restrict fp )

int puts ( const char *str )

函数 fputs 将一个以 null 字节终止的字符串写到指定的流,尾端的null不写出。

函数 puts 将一个以 null 字节终止的字符串写到标准输出,终止符不写出。但随后将一个换行符写到标准输出。

应当尽量使用 fgtes 和 fputs。

标准 I/O 的效率

二进制 I/O

以下两个函数用于执行二进制 I/O 操作

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

UNIX环境高级编程 标准IO库的更多相关文章

  1. UNIX环境高级编程---标准I/O库

    前言:我想大家学习C语言接触过的第一个函数应该是printf,但是我们真正理解它了吗?最近看Linux以及网络编程这块,我觉得I/O这块很难理解.以前从来没认识到Unix I/O和C标准库I/O函数压 ...

  2. UNIX环境高级编程——标准I/O库

    对一个进程预定义了三个流,并且这三个流可以自动的被进程使用,它们是:标准输入.标准输出.和标准错误. 标准I/O库提供缓冲的目的是尽可能减少使用read和write的次数. 标准I/O库提供了三种类型 ...

  3. UNIX环境高级编程——标准I/O库缓冲区和内核缓冲区的区别

    1.C标准库的I/O缓冲区         UNIX的传统 是Everything is a file,键盘.显示器.串口.磁盘等设备在/dev 目录下都有一个特殊的设备文件与之对应,这些设备文件也可 ...

  4. UNIX环境高级编程——标准I/O库函数和Unbuffered I/O函数

    以写文件为例,C标准I/O库函数(printf(3) .putchar(3) .fputs(3) )与系统调用write(2) 的关 系如下图所示. 库函数与系统调用的层次关系 open .read ...

  5. UNIX环境高级编程——标准IO-实现查看所有用户

    #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h&g ...

  6. (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  7. (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  8. (十一) 一起学 Unix 环境高级编程 (APUE) 之 高级 IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  9. Unix环境高级编程:文件 IO 原子性 与 状态 共享

    参考 UnixUnix环境高级编程 第三章 文件IO 偏移共享 单进程单文件描述符 在只有一个进程时,打开一个文件,对该文件描述符进行写入操作后,后续的写入操作会在原来偏移的基础上进行,这样就可以实现 ...

随机推荐

  1. Tomcat的配置,设置内存,获取用户IP

    一.修改配置文件 tomcat配置文件路径/tomcat/bin/server.xml # shutdown指定终止Tomcat服务器运行时,发给Tomcat 服务器的shutdown监听端口的字符串 ...

  2. 解题报告:hdu1257 LIS裸题

    2017-09-02 17:28:44 writer:pprp 那个裸题练练手,讲解在之前的博客中提到了 代码如下: /* @theme:hdu1257 @writer:pprp @begin:17: ...

  3. Spring MVC 实践笔记

    1.了解 Maven 的用法:http://spring.io/guides/gs/maven/ .这篇英文非常详细的演示了 Maven 的用法,在命令行下执行.注意,运行Maven的时候,Maven ...

  4. django学习错误笔记

    1.运行python manage.py makemigrations polls 出现错误

  5. 30分钟掌握Dart语言

    在Dart中,一切都是对象,一切对象都是class的实例,哪怕是数字类型.方法甚至null都是对象,所有的对象都是继承自Object 虽然Dart是强类型语言,但变量类型是可选的因为Dart可以自动推 ...

  6. Linux加载/usr/local/lib中的so库

    > https://my.oschina.net/u/2306127/blog/1617233 > https://blog.csdn.net/csfreebird/article/det ...

  7. thinkphp3.2笔记(1)目录,控制器及url模式,地址解析

    一.目录 Application  :  tp默认的应用代码存储的目录 Public :     Tp 默认的存储静态资源的目录,img,css,js ThinkPHP  :   Tp  框架的源代码 ...

  8. intent Filter

    intent Filter 一.介绍 如果一个 Intent 请求在一片数据上执行一个动作, Android 如何知道哪个应用程序(和组件)能用来响应这个请求呢? Intent Filter就是 用来 ...

  9. 委托---.net4.0提供两个比较重要的委托

    public delegate void Action<[in T1][,in T2][,in T3]......>([T1 t1][,T2 t2][,T3 t3]...) public ...

  10. 1-13 RHEL7-硬盘介绍和磁盘管理

    熟悉Linux平台下的存储介质,LVM逻辑卷.RAID 磁盘陈列等 大纲: 1-1  硬盘的分类及使用fdisk分区工具       1-1-1 认识硬盘的分类和特性.SCSI.IDE.SAS.SAT ...