文件操作是实际应用的重要部分,本文基于C程序设计(谭浩强版)所写。
C语言文件读写
fopen,fclose(打开关闭文件)
FILE *文件指针;// FILE *fp;
fopen(文件名,使用文件方式);//fp = fopen("file","r");
fclose(文件指针);//close(fp);
如果不能打开文件,fopen函数返回空指针值NULL。可能原因:文件不存在,磁盘故障,磁盘已满等。
fclose成功执行返回0,否则返回EOF(-1)。
文件使用方式 | 含义 | 如果文件不存在 |
---|---|---|
r(只读) | 输入,打开文本文件 | 出错 |
w(只写) | 输出,打开文本文件 | 建立新文件 |
a(追加) | 向文本文件尾添加数据 | 出错 |
rb(只读) | 输入,打开二进制文件 | 出错 |
wb(只写) | 输出,打开二进制文件 | 建立新文件 |
ab(追加) | 向二进制文件尾添加数据 | 出错 |
r+(读写) | 读写,打开文本文件 | 出错 |
w+(读写) | 读写,建立新的文本文件 | 建立新文件 |
a+(读写) | 读写,打开文本文件 | 出错 |
rb+(读写) | 读写,打开二进制文件 | 出错 |
wb+(读写) | 读写,建立新的二进制文件 | 建立新文件 |
ab+(读写) | 读写,打开二进制文件 | 出错 |
示例:
File *fp;
//打开
if((fp = fopen("D:\\fp.txt","r"))==NULL)
{
printf("文件打开失败!");
exit(0);
}
//关闭
fclose(fp);
顺序读写文件
fgetc,fputc(读写字符)
int fgetc(FILE *stream);//fgetc(fp);
int fputc (char c, File *fp);//fputc("hello",fp);
读写成功,返回所读写的字符的ASCII码的十进制值。失败返回EOF(-1)。
返回值是int型,所以应该用int ch; ch = fget(fp);
接受读取到的字符。
fgetc()与getc()/fputc()与putc()作用一样。
示例:
while(!feof(fp))
{
ch = fgetc(fp);
fputc(ch,fp2);
}
fgets,fputs(读写字符串)
char *fgets(char *str, int n, FILE *fp);
int fputs(char *str,FILE *fp);
*str:字符型指针,指向用来存储所得数据的地址。
n:整型数据,指明存储数据的大小。
*fp:文件结构体指针,将要读取/写入的文件流。
fgets成功:返回str数组首元素的地址;失败:一开始就遇到文件尾或者读数据出错,返回NULL。
fputs成功:返回0;失败:返回非0值。
fgets实际上读入n-1个字符,然后在最后加一个'\0',这样一共是n个字符,把它们放到字符数组str中。如果在读完n-1个字符前遇到'\n'或者文件结束符EOF,读入结束,但是'\n'也作为一个字符读入。
fputs的第一个参数可以是字符串常量、字符数组名或字符型指针。字符串结尾的'\0'不输出。
fgets、fputs类似于gets、puts,但是后者以终端为读写对象,前者以特定的文件为读写对象。
示例:
FILE *f1,*f2;
char str[10][10];
int i = 0;
if((f1=fopen("D:\\in.txt","r")) == NULL)
{
printf("can not open the file!");
}
if((f2=fopen("D:\\out.txt","w+")) == NULL)
{
printf("can not open the file!");
}
while(fgets(str[i],10,f1) != NULL)
{
//printf("%d,%s\n",i,str[i]);
fprintf(f2,"%s",str[i]);
i++;
}
fclose(f1);
fclose(f2);
fscanf,fprintf(格式化读写文件)
fscanf(文件指针,格式字符串,输入表列);
fprintf(文件指针,格式字符串,输出表列);
示例:
fscanf(fp,"%d,%f",&i,&f);
fprintf(fp,"%d,%6.2f",i,f);
类似于scanf,printf。
fscanf,fprintf对磁盘文件读写方便,容易理解。但是输入是要将文件中的ASCII码转换成二进制形式再保存在内存变量中,输出时又要将内存中的二进制形式转换成字符,要花费较多时间。因此,在内存与磁盘频繁交换数据的情况下,最好不用fscanf,fprintf。
fread,fwrite(用二进制方式读写)
fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
buffer:地址。对于fread,是存放从文件读入数据的存储区的地址;对于fwrite,是要把此地址开始的存储区中的数据向文件输出。均为起始地址。
size:要读写的字节数。count:要读写多少个数据项(每个数据项长度为size)。
fp:FILE类型指针。
fread,fwrite函数的类型为int型,如果函数执行成功,则返回形参count的值,即输入或输出数据项的个数。
示例:
fread(f,4,10,fp);
其中f是一个float型数组名(数组首元素地址)。从fp所指向的文件读入4个字节的数据,存储到数组f中。
struct Student_type
{
char name[10];
int num;
int age;
char addr[30];
}stud[40];
for (i=0;i<40;i++)
{
//每次从fp指向的文件读入结构体数组stu的一个元素
fread(&stud[i],sizeof(struct Student_type),1,fp);
//讲内存中的学生数据写入到磁盘文件中去
fwrite(&stud[i],sizeof(struct Student_type),1,fp2);
}
//实例:向文件中写入若干结构体数据并进行读取。=
#include <iostream>
#include <stdlib.h>
#define SIZE 1
struct Student_type
{
char name[10];
int num;
int age;
char addr[15];
}stud[SIZE];
void save()
{
FILE *fp;
int i;
if((fp=fopen("D:\\stu","wb"))==NULL)
{
printf("err");
exit(0);
}
for(i=0;i<SIZE;i++)
if (fwrite(&stud[i],sizeof(struct Student_type),1,fp)!=1)
{
printf("error");
}
fclose(fp);
}
void read()
{
FILE *fp;
int i;
if((fp=fopen("D:\\stu","rb"))==NULL)
{
printf("err");
exit(0);
}
for(i=0;i<SIZE;i++)
{
if(fread(&stud[i],sizeof(struct Student_type),1,fp)!=1)
{
printf("error");
};
printf("%-10s %4d %4d %-15s\n",stud[i].name,stud[i].num,stud[i].age,stud[i].addr);
}
fclose(fp);
}
int main()
{
int i;
printf("请输入10组学生数据:\n");
for (i=0;i<SIZE;i++)
{
scanf("%s%d%d%s",stud[i].name,&stud[i].num,&stud[i].age,stud[i].addr);
}
save();
read();
system("pause");
return 0;
}
随机读写文件
rewind
rewind(fp);
使文件位置标记指向文件开头。函数没有返回值。
fseek
fseek(文件类型指针,位移量,起始点)
起始点:用0,1,2代替。0(SEEK_SET):文件开始位置;1(SEEK_CUR):当前位置;2(SEEK_END):文件末尾位置。
位移量:以“起始点”为几点,向前移动的字节数。位移量应是long型数据(在数字的末尾加一个字母L,就表示是long型)。
fseek函数一般用于二进制文件。
示例:
fseek(fp,100L,0);//将文件位置标记向前移到离文件开头100个字节处。
fseek(fp,50L,1);//将文件位置标记向前移到离当前位置50个字节处。
fseek(fp,-10L,2);//将文件位置标记从文件末尾处向后退10个字节。
ftell
ftell(fp);
测定文件位置标记的当前位置。用相对于文件开头的位移量来表示。
如果调用函数时出错,ftell函数返回值为-1L。
示例:
i = ftell(fp);
if(i==-1L)
{
printf("error");
}
出错检测
ferror
ferror(fp);
调用输入输出函数(fputc,fgetc,fread,fwrite等)时,如果出现错误,除了函数返回值有所反映,还可以用ferror检查。
未出错:返回值为0;出错:返回非零值。执行fopen时,ferror自动置0。
clearerr
clearerr(fp);
使文件错误标志和文件结束标志置为0.