一.文件的打开与关闭
1.定义文件指针的一般形式:FILE *指针变量标识符
2.C语言中有三个特殊的文件指针无需定义、打开可直接使用:
stdin:标准输入,默认为当前终端(键盘)
我们使用的scanf、getchar、函数默认从此终端获得数据
stdout:标准输出,默认为当前终端(屏幕)
我们使用的printf、puts函数默认输出信息到此终端
stderr:标准出错,默认为当前终端(屏幕)
当我们程序出错或使用perror函数时信息打印在此终端
3.打开文件
FILE *fp = NULL;
fp = fopen(文件名,文件打开方式);
• 文件名:要操作的文件的名字,可以包含路径信息
• 文件打开方式:"读"、"写"、"文本"、"二进制"等
• fp文件指针:指向被打开的文件,失败返回空,成功返回相应指针
例如:FILE *fp = NULL;
fp = fopen("test.txt","r");
if(fp == NULL)
printf("File open error ");
4.文件打开的几种方式:读写权限:r w a +
r:以只读方式打开文件
文件不存在,返回NULL
文件存在,返回文件指针,进行后续的读操作
w:以只写方式打开文件
文件不存在,以指定文件名创建此文件
若文件存在,清空文件内容,进行写操作
a:以追加方式打开文件
文件不存在,以指定文件名创建此文件(同w)
若文件存在,在文件的结尾处进行写操作
+:同时以读写打开打开指定文件
模式(b可以省略) | 功能 |
r或rb | 以只读方式打开一个文本文件(不创建文件) |
w或wb | 以写方式打开问价(使文件长度截断为0字节,创建一个文件) |
a或ab | 以添加方式打开问价,即在末尾添加内容,当文件不存在时,创建问价用于写 |
r+或rb+ | 以可读、可写的方式打开文件(不创建新文件) |
w+或wb+ | 以可读、可写的方式打开文件(使文件长度为0字节,创建一个文件) |
a+或ab+ | 以添加方式打开文件,打开文件并在末尾更改文件(如果文件不存在,则创建文件) |
5.关闭文件
• 调用形式:fclose(文件指针);
文件指针:指向要关闭的文件
• 返回值:关闭文件成功,返回值为0
关闭文件失败,返回值非0
例如:FILE *fp = NULL;
fp = fopen("test.txt","r");
fclose(fp);
二.文件的顺序读写
1.字节读写函数:fgetc()和fputc()
♦ ch = fgetc(fp); //读一个字节
从指定文件读一个字节赋给ch
文本文件:读到文件末尾返回EOF(EOF值为1)
二进制文件:读到文件结尾,使用feof判断结尾
♦ fputc(ch,fp); //写一个字节
把ch变量中的值(一个字节)写到指定的问价
如果输出成功,则返回输出的字节
如果输出失败,则返回一个EOF
//从指定文件读取所有信息打印在屏幕上 #include <stdio.h> int main(int argc,char *argv[]) { FILE *fp; char ch; fp = fopen("1.c","r+"); if(fp == NULL) { printf("file open error "); return -1; } while((ch = fgetc(fp)) != EOF) printf("%c",ch); printf(" "); fclose(fp); return 0; }
2.字符串读写函数:fgets()和fputs()
♦ fgets(str,n,fp); //读一个字符串
从fp指向的文件中读入n-1个字符保存在str指向的内存中,'str为存放数据的首地址
在读入n-1个字符之前遇到换行符或EOF,读入提前结束,在最后加一个'
♦ fputs("china",fp); //写一个字符串
向fp指定的文件写一个字符串
第一个参数可以是字符串常量、字符数组名或字符指针,字符串末尾的' '不会写到文件
//从指定文件读取一个字符串写到另一个文件中 #include <stdio.h> int main(int argc,char *argv[]) { FILE *fp_read,*fp_write; char str[100]; fp_read = fopen("1.c","r+"); if(fp_read == NULL) { printf("1.c file open error "); return -1; } fp_write = fopen("dest.c","w+"); if(fp_write == NULL) { printf("dest.c file open error "); return -1; } fgets(str,80,fp_read); fputs(str,fp_write); fclose(fp_read); fclose(fp_write); return 0; }
3.数据块读写函数:fread()和fwrite()
♦ fwrite(buffer,size,count,fp); //将buffer中的内容写入到fp所指向的文件中
♦ fread(buffer,size,count,fp); //将fp所指向的文件中的内容读入到buffer内存中
参数说明:buffer:指向存储数据空间的首地址的指针
size:一次读写的数据库大小
count:要读写的数据块个数
fp:指向要进行写操作的文件指针
返回值:实际读写的数据块数,不是总数据大小,不到1块返回0,不到2块返回1
//从键盘输入一个结构体数据,输出到文件,在读出并显示在屏幕上 #include <stdio.h> struct stu { int num; int age; char name[10]; }boy1[2],boy2[2]; int main(int argc,char *argv[]) { FILE *fp; int i; printf("input num age name "); for(i=0;i<2;i++) scanf("%d %d %s",&boy1[i].num,&boy1[i].age,boy1[i].name); fp = fopen("dest.c","w+"); if(fp == NULL) { printf("dest.c file open error "); return -1; } fwrite(boy1,sizeof(struct stu),2,fp); //将学生信息写入到文件中 rewind(fp); //文件指针经写操作移到了最后,复位到开始处 fread(boy2,sizeof(struct stu),2,fp); //将文件中的数据读入到内存中 for(i=0;i<2;i++) printf("boy2[%d].num = %d,boy2[%d].age = %d,boy2[%d].name = %s ",i,boy2[i].num,i,boy2[i].age,i,boy2[i].name); fclose(fp); return 0; }
4.格式化读写函数:fscanf()和fprintf()
♦ fprintf(文件指针,格式字符串,输出列表);
例如:fprintf(fp,"%d,%6.2f",i,f); //将int型变量i和float型变量的值按%d和%6.2f的格式输出到fp指向的文件中
♦ fscanf(文件指针,格式字符串,输入列表);
例如:fscanf(fp,"%d,%f",&i,&f); //从磁盘文件中读取整型值存到变量i中,读取事型值存到变量f中
//从键盘写入一组数据,写入文件,在读出 #include <stdio.h> int main(int argc,char *argv[]) { FILE *fp; char name1[10] = "Bob",name2[10]; int age1 = 25,age2; float score1 = 90.5,score2; fp = fopen("dest.c","w+"); if(fp == NULL) { printf("dest.c file open error "); return -1; } fprintf(fp,"%s %d %f",name1,age1,score1); rewind(fp); //文件指针经写操作移到了最后,复位到开始处 fscanf(fp,"%s %d %f",name2,&age2,&score2); printf("name2 = %s age2 = %d score2 =%f ",name2,age2,score2); fclose(fp); return 0; }
三.文件的随机读写
1.rewind函数 void rewind(文件指针);
♦ 调用形式:rewind(文件指针);
♦ 函数功能:把文件内部的位置指针移到文件首
例如:fwrite(pa,sizeof(struct stu),2,fp);
rewind(fp);
fread(pb,sizeof(struct stu),2,fp);
2.ftell函数(测文件长度)
♦ 定义函数:long ftell(文件指针);
♦ 函数功能: 取得文件流目前的读写位置
♦ 返回值:返回当前位置(距离文件起始的字节数),出错时返回-1
例如:int length;
length = ftell(fp);
3.fseek函数(一般用于二进制文件)
♦ 定义函数:int fseek(文件类型指针,位移量,起始点);
♦ 函数功能:移动文件流的读写位置
•说明:文件开头 SEEK_SET 0
文件当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2
• 位移量:以起始点为基点,向前后移动的字节数
♦ 函数应用举例
• fseek(fp,100,SEEK_SET); 将位置指针从文件头向前移100个字节处
• fseek(fp,50,SEEK_CUR); 将位置指针从当前位置向前移动50个字节
• fseek(fp,-50,SEEK_CUR); 将位置指针从当前位置向回移动50个字节处
• fseek(fp,-50,SEEK_END); 将位置指针从文件尾退回50个字节处
//往文件中写入两个结构体,读取第二个结构体 #include <stdio.h> struct stu { int num; int age; char name[10]; }boy1[2],boy2; int main(int argc,char *argv[]) { FILE *fp; int i; printf("input num age name "); for(i=0;i<2;i++) scanf("%d %d %s",&boy1[i].num,&boy1[i].age,boy1[i].name); fp = fopen("dest.c","w+"); if(fp == NULL) { printf("dest.c file open error "); return -1; } fwrite(boy1,sizeof(struct stu),2,fp); //将学生信息写入到文件中 fseek(fp,sizeof(struct stu),SEEK_SET); fread(&boy2,1,sizeof(struct stu),fp); //将文件中的数据读入到内存中 printf("boy2.num = %d,boy2.age = %d,boy2.name = %s ",boy2.num,boy2.age,boy2.name); fclose(fp); return 0; }
四.文件的出错监测
1.文件结束检测函数feof
♦ 调用函数:feof(文件指针);
♦ 功能:判断文件是否处于文件结束位置,常配合fgetc、fgets、fread等读函数判断是否到文件结束
♦ 返回值:文件未结束返回0,文件已结束返回非0
//文件结束检测 #include <stdio.h> int main(int argc,char *argv[]) { FILE *fp; char str; fp = fopen("dest.c","r+"); if(fp == NULL) { printf("dest.c file open error "); return -1; } while(1) { str = fgetc(fp); if(feof(fp) != 0) break; printf("%c",str); } fclose(fp); return 0; }
2.读写文件出错检测函数ferror
♦ 调用格式:ferror(文件指针);
♦ 功能:检查文件在用各种输入输出函数进行读写时是否出错
比如:以只读方式打开一个文件,调用写函数就会发生错误。
只要出现错误标志,就一直保留,直到对同一文件调用clearerr函数或rewind函数,或任何一个其它输入输出函数。
♦ 返回值:为0表示未出错,否则表示有错
//读写文件出错检测函数 #include <stdio.h> int main(int argc,char *argv[]) { FILE *fp; char str; fp = fopen("dest.c","r+"); str = getc(fp); if(ferror(fp)) { printf("error reading from dest.c "); clearerr(fp); } fclose(fp); return 0; }
3.文件出错标志和文件结束标志置0函数clearerr
♦ 调用格式:clearerr(文件指针);
♦ 功能:本函数用于清除出错标志和文件结束标志,使它们为0值
♦ 无返回值