函数简介篇——文件流与C库函数

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
内容来源
  菜鸟教程-stdio.hC语言中文网百分网-C语言的文件概念博客园-FILE结构体知乎-一切皆文件博客园-Linux-struct file
  具体函数使用细节看上面参考来源网站。

概念

  1️⃣什么是文件?
  ①文件就是保存数据的一种机制
    数据:一连串字符(字符序列)组成。
  ②Linux思想:一切皆文件。即:所有东西都可通过文件的形式单方面的访问/呈现(不是文件也以文件规范访问,但不可反向创建)。
    好处:省心(统一操作,简化接口)。
  2️⃣什么是文件流?
  前提知识
    磁盘:数据(文件)存储不丢失的地方。    内存:处理数据的地方。
    字符集:ASCII字符集:一字符一个字节。    国际字符集:一字符多字节
  文件流:文件在磁盘与内存之间传递的过程。
    输入流:从磁盘到内存的过程。    输出流:从内存到磁盘的过程。
    流定向:决定所读、写字符是单字节还是多字节。freopen():清除流定向,fwide()设置流定向】
  故:打开文件就到打开一个流(流提供了文件和程序的通信通道)。
  3️⃣如何描述文件?
  C语言中定义一个存储文件流信息的对象:FILE库变量。
  FILE结构体:由系统定义的结构体,含有文件相关信息,如:文件名、文件状态、当前读写位置、文件描述符等。
    文件描述符:操作系统数组(打开文件列表的索引)。每个数组元素包含一个文件控制块(FCB, File Control Block),操作系统用它来管理特定的文件。
  FILE *fp:文件指针(file pointer):指向文件,通过它对文件进行各种操作(找到对应文件信息结构体变量,再根据结构体变量找到该文件实施对文件的操作)。
  4️⃣如何操作文件?
  一般步骤:打开文件 --> 读写文件 --> 关闭文件。
    打开文件:建立和文件的关系。【文件指针指向FILE结构体变量】
    读写文件
    多种读写方式;
      1.一个字符。2.若干字节。3.一整行。
    读写位置灵活:
      1.文件头。2.文件中。
    关闭文件:断开和文件的关系。【文件指针断开FILE结构体变量,禁止文件操作】
  5️⃣三个标准流
    stdin:标准输入、stdout标准输出、stderr标准出错。
  6️⃣缓冲
    目的:减少IO函数调用次数
    类型setbuf()打开或关闭缓冲,setvbuf()设置指定缓冲类型】
      ①全/块缓冲:填满缓冲区后才进行IO操作(flush:将缓冲区内容写到磁盘上)。
      ②行缓冲:遇见换行符时才进行IO操作(涉及终端一般为行缓存:stdin,stdout)
      ③不带缓冲:不对字符进行缓冲存储。(stderr)
请添加图片描述

函数介绍

一、缓冲文件流

1️⃣ setbuf()、setbuffer() 、setlinebuf()、setvbuf()—— 流缓冲操作
#include <stdio.h>
void setbuf(FILE *stream, char *buf);							/定义流stream应如何缓冲。该函数应在与流stream相关的文件被打开时,且还未发生任何输入或输出操作之前被调用一次
void setbuffer(FILE *stream, char *buf, size_t size);			/定义流 stream 应如何缓冲。
void setlinebuf(FILE *stream);
int setvbuf(FILE *stream, char *buf, int mode, size_t size);

stream :文件流   buf:缓冲区   size:缓冲区大小  mode:模式
return:成功返回0,失败返回非0并设置errno

  mode选项
    _IONBF:unbuffered——不带缓冲
    _IOLBF :line buffered——行缓冲
    _IOFBF: fully buffered——全缓冲

2️⃣ fflush() ——冲洗流
#include <stdio.h>
int fflush(FILE *stream);			/强制写入给定输出或更新流的所有用户空间缓冲数据。

stream :文件流
return:成功回0。否则返回EOF,并设置errno指示错误。
3️⃣fwide() ——设置和确定FILE流的方向
#include <wchar.h>
int fwide(FILE *stream, int mode);					/设置和确定FILE流的方向

stream :文件流		mode :模式
mode:正数-》宽字节,负数-》单字节,0-》未决定

  注意:fwide()不改变已定向流的定向,一旦流有了方向,它就不能被更改并一直保持到流关闭。

二、操作文件流

1️⃣ fopen()、fdopen()、freopen()——打开流
 #include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);					
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *pathname, const char *mode, FILE *stream);

pathname:文件路径名  mode:模式  fd:文件描述符  stream:文件流
return:指向FILE结构体指针(指向该文件信息保存的结构体中),若打开失败则返回空指针。

  fopen():以mode方式打开filename指向的文件,同时将文件相关信息存到FILE文件表中[文件表].
  fdopen():获取现有文件描述符fd,并使标准IO流与该描述符相结合。
  freopen(): 从指定流stream上打开filename指向的文件,若流已打开则先关闭,若流已定向则清除。【常用于指定文件打开预定义的流:标准输入、标准输出、标准出错】
  mode:由 r(read,读)、w(write,写)、a(append,追加)、t(text,文本文件)、b(binary,二进制文件)、+(读和写) 六个字符拼成.
注意事项
  ①"r"的文件必须存在。
  ②“a”文件不存在则创建,存在则追加。
  ③"w"文件不存在则创建,存在则删除在创建。
  ④"t"与b":并无本质区别,只是对换行符的处理不同。

2️⃣ fclose() —— 关闭流
#include <stdio.h>
int fclose(FILE *fp)	/刷新stream指向的流(使用fflush(3)写入任何缓冲的输出数据),并关闭底层的文件描述符。

fp: 指向FILE对象的指针,该FILE对象指定了要被关闭的流。
return:关闭成功返回0,失败返回EOF

三、读写文件流:

  三种类型的非格式化I/O操作

序号 类型 函数 注意
1️⃣ 每次一个字符的I/O getc()、fgetc()、getchar()
fputc() 、putc() 、putchar()
若流带缓冲则会处理所有缓冲
2️⃣ 每次一行的I/O gets() 、fgets()
puts() 、fputs()
每行以换行符终止,且注意最大行长
3️⃣ 直接I/O fread()
fwrite()
每次读写某种数量对象,每个对象具有指定长度
1️⃣ fgetc() 、getc() 、getchar()——输入字符
#include <stdio.h>
int fgetc(FILE *stream);			/从流中读取下一个字符,并将其作为无符号字符转换为int型,或在文件结束或错误时返回EOFint getc(FILE *stream);				/fgetc()是等价的,除了它可以被实现为一个宏,对流进行多次计算。
int getchar(void);					/等价于gettc (stdin)。

stream:文件流
return:文件或错误结束时返回读取为unsigned char类型的字符,并将其转换为intEOF类型。
1️⃣ fputc() 、putc() 、putchar()——输出字符
 #include <stdio.h>
int fputc(int c, FILE *stream);		/将转换为unsigned char的字符c写入流。
int putc(int c, FILE *stream);		/fputc()是等价的,除了它可以被实现为一个对流进行多次计算的宏。
int putchar(int c);					/putchar(c)等价于putc(c, stdout)。

 c:符号    stream:文件流
 return:返回以unsigned char形式写入的字符,并将其转换为int型或EOF
2️⃣ gets() 、fgets() ——输入字符串
#include <stdio.h>
char *gets(char *s);  							 /stdin中读取一行到s所指向的缓冲区中,直到出现结束的换行符或EOF,并用空字节('\0')替换。
char *fgets(char *s, int size, FILE *stream);    /最多从流中读取一个小于size的字符,并将其存储到s所指向的缓冲区中。在EOF或换行符之后停止读取。如果读取了换行符,则将其存储到缓冲区中。一个终止的空字节('\0')被存储在缓冲区的最后一个字符之后。

s:缓冲区  size:字节大小    stream:文件流
return:成功返回s,在错误时返回NULL或在文件结束时没有读取字符。
2️⃣ puts() 、fputs() —— 输出字符串
#include <stdio.h>
int puts(const char *s);					/将字符串s和末尾的换行符写入标准输出。
int fputs(const char *s, FILE *stream);		/将字符串s写入流,而不将其终止为空字节('\0')。

s:字符串    stream:文件流
return:成功时返回一个非负数,出错时返回EOF
3️⃣ fread() —— 输入二进制流[必须以"b"形式打开文件]
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);	/从stream指向的流中读nmemb数据项,每个数据项大小为size字节长,并将它们存储在ptr给出的位置。

ptr:存储空间      size:字节大小   nmemb:数据项数    stream:文件流
return:若成功将返回读取的条目数。条目数等于仅当size为1时传输的字节数。若发生错误或到文件末尾,则返回值是一个短项计数(0)
3️⃣ fwrite() —— 输出二进制流[必须以"b"形式打开文件]
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);	/将大小为size字节长的nmemb数据项写入到stream所指向的流中,从ptr给出的位置获取它们

ptr:存储空间      size:字节大小   nmemb:数据项数    stream:文件流
return:若成功将返回写入的条目数。条目数等于仅当size为1时传输的字节数。若发生错误或到文件末尾,则返回值是一个短项计数(0)

四、定位文件流

rewind()——设置文件位置为开头

  相当于:(void) fseek(stream, 0L, SEEK_SET)

#include <stdio.h>
void rewind(FILE *stream);			/为流所指向的流设置文件位置指示器到文件的开头

stream:文件流

三种方法定位IO流

序号 类型 函数 注意
1️⃣ 偏移量为长整型 fseek():设置流位置
ftell() :获取流位置
2️⃣ 偏移量为off_t型 ftello()
fseeko()
3️⃣ 文件位置用fpos_t表示 fgetpos()
fsetpos()
fseek() 、ftell() 、ftello() 、fseeko() 、fgetpos() 、fsetpos()—— 设置/获取文件流位置
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);		/设置流所指向的流的文件位置指示器。
long ftell(FILE *stream);								/获取流所指向的流的文件位置指示器的当前值
int fseeko(FILE *stream, off_t offset, int whence);	/等价于fseek()
off_t ftello(FILE *stream);							/等价于ftell()
int fsetpos(FILE *stream, const fpos_t *pos);	/等价于fseek()
int fgetpos(FILE *stream, fpos_t *pos);			/等价于ftell()

stream:文件流  offset:偏移量    whence:位置标志
return:fseek()/fseeko()返回0,而ftell()/ftello()返回当前偏移量。否则返回-1并设置errno表示错误。

  whence参数

起始位置 常量名 常量值
文件开头 SEEK_SET 0
当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2

五、格式化I/O

1️⃣格式化输入
#include <stdio.h>
int scanf(const char *format, ...);									/输入字符串,并将字符序列转换成指定类型变量
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

format:格式控制字符串 ...:参数列表。   stream:文件流      str:存储空间

#include <stdarg.h>
int vscanf(const char *format, va_list ap);
int vsscanf(const char *str, const char *format, va_list ap);
int vfscanf(FILE *stream, const char *format, va_list ap);

  格式说明([]表示可选部分)

%[*][fldwidth][lenmodefier]convtype
(1* 用于抑制转换。按转换说明的其余部分对输人进行转换,但转换结果并不存放在参数中。
(2)fldwidth:说明最大宽度(即最大字符数)。
(3)lenmodifier:说明要用转换结果初始化的参数大小。
convtype 转换类型

在这里插入图片描述

2️⃣格式化输出
#include <stdio.h>
int printf(const char *format, ...);								/将格式化数据写到标准输出
int fprintf(FILE *stream, const char *format, ...);					/将格式化数据写到指定文件流
int dprintf(int fd, const char *format, ...);						/将格式化数据写到指定文件描述符
int sprintf(char *str, const char *format, ...);					/将格式化数据写到指定数组str,自动加null,。但该字节不包括在返回值中
int snprintf(char *str, size_t size, const char *format, ...);		/将格式化数据写到指定数组str,并设置缓冲区长度

format:格式控制字符串 ...:参数列表。   stream:文件流     fd:文件描述符   str:存储空间

#include <stdarg.h>
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vdprintf(int fd, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);

  格式说明([]表示可选部分)

%[flags][fldwidth][precision][lenmodefier]convtype

(1)flag:标识
		-:在字段内左对齐输出
		+;总是显示带符号转换的符号
		空格:若第一个字符不是符号,则在其前面加上一个空格
		#:指定另一种转换形式 
		0:添加前导0(而非空格)进行填充
(2)fldwidth:说明转换的最小字段宽度。
(3)precision:说明整型转换后最少输出数字位数、浮点转换后小数点后的最少位数,字符串转换后的最大字符数。
(4)lenmodefier:参数长度
		hh  有符号或无符号的char
		h   有符号或无符号的short
		l	有符号或无符号的long或者宽字符
		11	有符号或无符号的long long
		j	intmax_t或uintmax t
		z	size_t
		t	ptrdiff_t
		L	long double
convtype 转换类型

在这里插入图片描述

六、检测文件

clearerr() 、feof() 、ferror()、fileno()——检查和重置文件流状态
#include <stdio.h>
void clearerr(FILE *stream);		/清除由stream指向的流的文件结束符和错误指示符。
int feof(FILE *stream);				/(检查文件是否处于结束位置)测试stream所指向的流的文件结束指示器,如果设置了该指示器,则返回非零值。文件结束指示器只能由clearerr()函数清除。
int ferror(FILE *stream);			/(检查文件读写时是否出错)测试stream所指向的流的错误指示符,如果设置了,则返回非零值。错误指示符只能由clearerr()函数重置。
int fileno(FILE *stream);			/检查参数流并返回用于实现该流的整型文件描述符。文件描述符仍然归stream所有,当调用fclose(3)时将被关闭。在将文件描述符传递给可能关闭它的代码之前,使用dup(2)复制它。

stream:文件流
return:clearerr()这不会失败....其他当位置指针为文件结束标识符则返回非零,否则返回零.
		

七、临时文件

tmpfile() ——创建临时文件
#include <stdio.h>
FILE *tmpfile(void)		/以二进制读写模式(wb+)创建临时文件,在流关闭的时或程序终止的时自动删除。

return:若成功返回一个指向被创建的临时文件的流指针。若文件未被创建,则返回NULL
tmpnam()——为临时文件取名
#include <stdio.h>
char *tmpnam(char *s);			/产生一个与现有文件名不同的一个有效名字符串   /因此具有此名称的文件在某个时间点不存在,因此无知的程序员可能会认为它适合用于临时文件。如果参数s为NULL,则在内部静态缓冲区中生成此名称,并可能被下一次调用tmpnam()所覆盖。如果s不为NULL,名称被复制到s所指向的字符数组(长度至少为L_tmpnam),如果成功则返回s的值。
char *tempnam(const char *dir, const char *pfx);	/允许调用者所产生路径名指定目录和前缀。     返回一个指向一个字符串的指针,该字符串是一个有效的文件名,因此当tempnam()检查时,带有此名称的文件不存在。生成的路径名的文件名后缀将以pfx开头,以防pfx是一个最多5个字节的非null字符串。生成的路径名的目录前缀部分需要是“适当的”(通常至少意味着可写)。

s:字符串
return:返回一个指向字符串的指针,该字符串是一个有效的文件名
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值