3.标准文件IO

标准IO库

标准IO库处理有很多细节,例如缓冲区分配、以优化的块长度执行IO等。

1.流和FILE对象

对于标准IO库,所有操作都是围绕进行的,当用标准IO库打开或创建一个文件时,就使一个流与一个文件相关联。

流的定向决定读写字符是单字节还是多字节字符集(多字节对应宽定向,单字节对应字节定向)。fwide用于设置流的定向:

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

由于fwide无出错返回,因此在调用fwide前先清除errno,从fwrite返回时,检查errno的值。

2.缓冲

为了不频繁使用writeread,标准IO库提供了缓冲:

  • 全缓冲,填满标准IO缓冲区后进行实际IO操作
  • 行缓冲,遇到换行符或者填满行缓冲区后进行操作
  • 不缓冲,不缓冲,直接输出

通过下列两个函数可以对缓冲类型进行修改:

#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参数说明所需的缓冲类型:

mode参数 类型
_IOFBF 全缓冲
_IOLBF 行缓冲
_IONBF 不缓冲

若不使用缓冲,则忽略bufsize参数。

3.打开流

下列3个函数用于打开流:

#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);
/* 返回值:成功返回文件指针,失败返回NULL */

三者区别在于:

  • fopen 打开路径名为pathname的一个指定文件
  • freopen 在一个指定的流上打开一个指定的文件,若该流已经打开,则先关闭该流。若该流已经定向,则使用freopen清除该定向。此函数一般用于将指定文件打开为一个预定义的流:标准输入,输出和错误
  • fdopen取一个已有的文件描述符(可能从open,dup,pipe,socket得到此描述符),并使一个标准IO流与该描述符向结合。此函数常用于创建管道和网络通信管道函数返回的描述符。

使用fclose可以关闭一个打开的流,在文件被关闭前,冲洗缓冲中的输出数据,并丢弃缓冲区中任何输入数据,并且释放此缓冲区。

一个进程正常终止时,则所有带未写缓冲数据的标志IO都会被冲洗,所有打开的标准IO流都被关闭。

4.读和写流

打开流之后,可以对其进行读写操作。

输入函数

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

#include <stdio.h> 
int getc(FILE *fp); 
int fgetc(FILE *fp); 
int getchar(void);
/* 返回值:成功返回下一个字符;若到达尾端或者出错返回EOF */

getchar等同于getc(stdin)。前两个函数区别在于,getc可被实现为宏,而fgetc不能,这就意味着:

  • getc的参数不应当具有副作用的表达式
  • fgetc一定是个函数,可以通过函数指针传递给另一个函数
  • 调用fgetc所需时间可能比getc更长

输出函数

对应输入函数都有一个输出函数:

#include <stdio.h>
int putc(int c, FILE *fp); 
int fputc(int c, FILE *fp); 
int putchar(int c);
/* 返回值:成功返回c,出错返回EOF*/

与输入函数一样,putchar(c)等同于putc(c,stdout)putc可以被实现为宏。

5.每次一行IO

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

#include <stdio.h>
char *fgets(char *restrict buf, int n, FILE *restrict fp); 
char *gets(char *buf);
/* 返回值:成返回buf;若到达尾端或者出错返回NULL*/

尽量使用fgets防止缓冲区溢出。

对应输出一行的功能:

#include <stdio.h>
int fputs(const char *restrict str, FILE *restrict fp); 
int puts(const char *str);
/* 返回值:成功返回非负值,出错返回EOF*/

fputs将一个null字节终止的字符串写到指定的流,puts除了null,随后添加了一个换行符到标准输出。

如果总是使用fgetsfputs,那么久会熟知在每行终止处我们必须字节处理换行符。

6.二进制IO

前面的输入函数只能一次性读取一个字节或者一行数据,为了获得整个结构,提供了下列两个函数用以执行二进制IO操作:

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

读写一个结构体,可以如下:

struct {
    short  count;
    long   total;
    char   name[NAMESIZE];
} item;
if (fwrite(&item, sizeof(item), 1, fp) != 1)
    err_sys("fwrite error");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容

  • tags:io categories:总结 date: 2017-03-28 22:49:50 不仅仅在JAVA领...
    行径行阅读 2,171评论 0 3
  • C/C++输入输出流总结 前两天写C++实习作业,突然发现I/O是那么的陌生,打了好长时间的文件都没有打开,今天终...
    LuckTime阅读 1,721评论 0 6
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,858评论 25 707
  • 最近几天忙着招待婆家的姐姐们。累!刚从河北回来,跑来跑去,脚,不再是我的了。夜晚没睡好,眼睛生痛。大家庭的热闹实在...
    老美子阅读 147评论 0 0