C标准库中的I/O操作

标准库中的I/O操作都是围绕流来操作的,而不是文件描述符。

流的定向

流的定向决定了所读、写的字符是单字节还是多字节的。当一个流最初被创建时,它并没有定向。如果在未被定向的流上使用一个多字节的I/O函数<wchar.h>定义中的函数,则将该流设置为宽定向的。相反,如果在为定向的流上使用一个单字节函数,则是字节定向的。

与流定向相关的函数:

#include<stdio.h>

#include<wchar.h>

int fwide(FILE *fp, int mode)

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

I/O缓冲区

I/O缓冲的目的是尽可能减少使用read和write调用的次数(频繁调用这两个系统调用会耗费不少运行时间),因此,当缓冲区满了的时候才调用读写函数是一种减少系统调用折中方法。

标准I/O提供了3种类型的

  • 全缓冲

适用于与磁盘等块设备交互场景。全缓冲是指,当缓冲区满了的时候才会调用读写系统调用,其他非满的时候,可以使用fflush刷新到磁盘。

  • 行缓冲

适用于与终端交互的场景,一般涉及到标准输入和标准输出,使用的都是行缓冲。行缓冲也是一块长度固定的内存,当行缓冲捕捉到’\n’字符的时候,会刷新到输入输出设备。或者,当行缓冲满了的时候,也会调用读写系统调用。

  • 无缓冲

无缓冲没有缓冲机制,也就是说直接调用读写调用。

涉及到缓冲的操作函数:

#include<stdio.h>

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

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

setbuf用于为打开的文件流指定缓冲区。buf为一个缓冲区指针

setvbuf与setbuf在setbuf的基础上进行了功能扩展,mode表示所指向的缓冲类

mode:

  • _IOFBF 全缓冲

  • _IOLBF 行缓冲

  • _IONBF 不带缓冲

如果指定了一个带缓冲的流,而buf是空的,那么函数会自动分配一个长度为size的缓冲区

与流相关的操作

(1)打开

#include<stdio.h>

FILE *fopen(const char *restrict pathname, const chr *restrict type)

FILE *freopen(const char *restrict pathname, const chr *restrict type,FILE* restrict fp)

FILE *fopen(int fd, const char *type)

fopen不用多数,freopen在一个指定的流上打开一个指定的文件,如果该流已经打开,则先关闭该流。如果该流已经定向,则使用freopen清除该定向。此函数一般用于将一个指定的文件打开一个预定义的流:标准输入、标准输出和标准错误。

fdopen为一个文件描述符寻找一个缓冲区。这些文件描述符可能从(open,dup,dup2,fcntl,pipe,socket,socketpair或accept)函数得到。此函数常用语由创建管道和网络通信函数返回的描述符,因为这些描述符不能标准I/O函数fopen打开,所以必须先调用设备专用函数以获得一个文件描述符,然后fdopen使一个标准I/O流与该描述符相结合。

-typeopen(2)-
r或rbO_RDONLY
w或wbO_WRONLY | O_CREAT|O_TRUNC
a或abO_WEONLY | O_CREAT | O_APPEND
r+或r+b或rb+O_RDWR
w+或w+b或wb+O_RDWR | O_CREAT | O_TRUNC
a+或a+b或ab+O_RDWR | O_CREAT | OAPPEND

(2)关闭

int fclose(FILE* fp);

(3)I/O标准库中的读写操作

#include<stdio.h>
int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);

int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);

getc(stdin)和getchart()效果相同。getc和fgetc的区别在于,前者可被用于宏定义,而后者只能被作为函数调用。也就是说fgetc的地址可以作为参数传递个其他函数,而getc不能。

当函数调用出错或到达文件尾端时,三个函数的返回值相同,因此需要配合下面两个函数进行判断:

#include<stdio.h>
int ferror(FILE *fp); //如果流读写出错,则返回1,否则返回0
int feof(FILT *fp); //如果流到达缓冲区末尾,则该函数返回1,否则返回0

void clearerr(FILE *fp); // 清楚FILE结构体中上述两个标志

使用示例:

while((c=getc(stdin) != EOF))
	if(put(c,stdout)==EOF)
		err_sys("output error");
if(ferroe(stdin))
	err_sys("input error");

(4) 每次一行I/O

#include<stdio.h>
char *fgets(char *restrict buf, int n, FILE *restrict fp);
char *gets(cahr *buf); //不推荐使用

int fputs(const cahr *restrict str, FILE *restrict fp);
int puts(const char *str);//不推荐使用

使用示例:

while(fgets(buf,MAXLINE,stdin) != NULL)
	if(fputs(buf,stdout)==EOF)
		err_sys("output error");
if(ferroe(stdin))
	err_sys("input error");

(5)二进制读写

#include<stdio.h>
int fread(void *restrict ptr,int size, int nobj,FILE *restrict fp);
int fwrite(const coid *restrict ptr, int size, int nobj, FILE *restrict fp);

size是一次读写多少个字节,nobj是一次读写几次,函数返回的是一次读写了几个size大小的内容。

(6)定位

#include<stdio.h>
long ftelll(FILE  *fp);
int fseek(FILE *fp, long offset, int whence);
void rewind(FILE *fd);

whence:

  • SEEK_SET 文件开头
  • SEEK_CUR 当前位置
  • SEEK_END 文件末尾
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值