文件操作
文件是什么
文件通常是在磁盘或固态硬盘上一段已命名的存储区。比如常见的 Word 、txt 、源文件、头文件等。文件是数据源的一种,最主要的作用是保存数据。在C里把文件看作是一系列连续的字节,每个字节都能单独读取。C提供两种文件模式:文本模式和二进制模式。
标准文件
C程序在执行时会自动打开以下三个文件(执行完毕后自动关闭):
stdin 标准输入,一般指键盘 例如scanf()、getchar()
stdout 标准输出,一般指显示屏 例如printf()、putchar()
stderr 标准错误,一般指显示屏 例如perror()
一个栗子
关闭“标准输出文件”后,可以看到“Hello world!”没有输出。
打开文件fopen()函数和关闭文件fclose()函数
fopen() 函数原型
FILE *fopen(char *filename, char *mode); //filename 文件名,mode 打开方式
FILE 是 <stdio.h> 中的一个结构体,它专门用来保存文件信息(文件名、文件状态、当前读写位置等)。
打开文件出错时,fopen() 将返回一个空指针,可以用这个来判断文件是否打开成功。
fclose()函数原型
int fclose(FILE *fp);
成功:函数返回零
失败:函数返回EOF。
文件使用完后,应关闭文件,以释放相关内存。
下面写一个打开文件的例子
#include<stdio.h>
int main()
{
FILE *fp=NULL;//先定义一个文件指针
if( (fp=fopen("test.txt","r")) == NULL ){
printf("Fail to open file!\n");
exit(0); //退出程序(结束程序)
}
fclose(fp); //关闭文件
return 0;
}
fopen() 函数的打开方式(默认为文本模式t / 可改为二进制模式b 。例 “rb”、“wb” )
“r” 只读。只允许读取,不允许写入。文件必须存在,否则打开失败。
“r+” 读写。既可以读取也可以写入,可随意更新文件。但是文件必须存在,否则打开失败。
“w” 写入。若文件不存在,那么就创建一个新文件;若文件存在,就清空文件内容。
"w+”写入/更新。既可以读取也可以写入,可随意更新文件。若文件不存在,就创建一个新文件;若文件存在,就清空文件内容。
“a” 追加。若文件不存在,创建一个新文件;若文件存在,将写入的数据追加到文件的末尾。
"a+”追加/更新。既可以读取也可以写入,可随意更新文件。若文件不存在就创建一个新文件;若文件存在,那么就将写入的数据追加到文件的末尾。
写入—读取文件
以单个字符的形式写入和读取文件
fputc( ) — fgetc( )
fputc( ) 写入函数原型
int fputc( int ch, FILE *fp ); //fputc 中的 c 表明是一个字符(char)
函数把参数 ch 的字符值写入到 fp 所指向的输出文件中。成功:返回写入的字符 失败:返回EOF
fgetc( ) 读取函数原型
int fgetc( FILE * fp ); //fgetc 中的 c 表明是一个字符(char)
函数从 fp 所指向的输入文件中读取一个字符。成功:返回读取的字符 失败:返回EOF
多个字符时可以借助循环进行写入和读取文件
文本文件的结束标记 EOF -1
写入
读取 到达 -1 后停止 这种方式不适合二进制文件
feof( )函数判断是否到达文件结尾
feof( ) 函数原型
int feof(FILE *stream); //这个函数需要用循环和fgetc 才能判断,只用feof函数的话光标不移动,无法判断。
到达文件结尾返回 :非零(真)
未到达文件结尾返回:零 (假)
读取
以字符串(行)的形式写入和读取文件
fputs( ) — fgets( ) * * * * * * fgets保留了换行符 fputs不会添加换行符
fputs( ) 写入函数原型
int fputs( char *buf, FILE *fp ); //fputs 中的 s 表明是一个字符串(string)
//fputs 在打印字符串时不会在末尾添加换行符\n.
buf为要写入的字符串的地址,fp 为文件指针。成功:返回非负数,失败:返回 EOF。
fgets( ) 读取函数原型(可以读取空格)
char *fgets ( char *buf, int n, FILE *fp ); //fgets 中的 s 表明是一个字符串(string)
//fgets 空间不足 在末尾添加一个空字符,使其成为一个完整的字符串。字符串的大小是(n-1)
//空间充足 读到换行符时存放换行符,并在换行符后加一个空字符。
buf 为字符数组,n 为要读取的字符数目,fp 为文件指针指定待读取的文件。
实际字符串大小为(n-1)
成功:返回字符数组首地址,失败:返回 NULL。
以字块的形式写入和读取文件
fwrite( ) — fread( )
fwrite( ) 写入函数原型
size_t fwrite ( void * ptr, size_t size, size_t count, FILE *fp );
参1:待写数据的地址
参2:待写数据的大小
参3:写入多少次
参4:文件地址
写入的总大小(总的字节数)=参2*参3
成功:返回参3的值
失败:返回0
fread( ) 读取函数原型
size_t fread ( void *ptr, size_t size, size_t count, FILE *fp );
参1:存放读到的数据的地址
参2:待读数据的大小
参3:读取多少次
参4:文件地址
读取的数据总大小(总的字节数)=参2*参3
成功:返回参3的值 ,若最后不足 count 次会返回实际读取的次数。
失败:返回0
格式化写入和读取文件
fscanf( )— fprintf( )
fscanf( ) 写入函数原型
int fscanf ( FILE *fp, char * format, ... );
参1:文件地址
参2:格式串
参3:参数列表
fprintf( ) 读取函数原型
int fprintf ( FILE *fp, char * format, ... );
参1:文件地址
参2:格式串
参3:参数列表
随机访问
fseek( ) 移动文件光标
int fseek ( FILE *stream, long offset, int origin );
参1:文件地址(已经打开的文件)
参2:偏移量(+向后 -向前 )
参3:模式
SEEK_SET 文件开始处
SEEK_CUR 当前位置
SEEK_END 文件末尾
ftell( ) 获取文件光标的位置
loong ftell(FILE *stream)
参:文件地址(已经打开的文件)
rewind( ) 将文件光标移动到文件开头
void rewind ( FILE *stream );
参:文件地址(已经打开的文件)