【C】文件的写入与读取
一、文件打开/关闭
打开:
FILE *fp=NULL;
fp=fopen("D:/desktop/chen.txt","r");
关闭:
fclose(fp);
二、文件使用方式
只有文本属于文本文件,其他如音乐、视频等都是二进制文件
文本文件:
r:只读 w:只写 a:尾部追加
r+:读写(如果文件不存在,打开失败)
w+:读写(建立一个新的文件,如果文件已经存在,就会把原来里面的内容清空)
a+:读写(尾部追加)二进制文件:
rb:只读
wb:只写
rb+:读写
wb+:读写
三、文件读取
1.
ch=fgetc(fp)从指定文件取得一个字符
feof(fp):feof读到文件末尾返回0
while(!feof(fp))
{
ch=fgetc(fp);//每执行一次,指针就偏移一个字符
printf("%c",ch);//如果用fgetc每次只读一个,效率低
}2.
fgets()从指定文件读取字符串(一行一行读取)
char buffer[50]={0};//一个读取缓冲区
char str_msg[50]="new file scample";
fgets(buffer,sizeof(byffer),fp);//前提是buffer足够大,能放下一行3.
fread():如果返回值为0,读到了文件末尾,30表示每次只读30个字节
fread(buffer,sizeof(char),30,fp);//执行完数据被写入数组中
使用缓冲区记得清除:
memset(buffer,0,sizeof(buffer));//打印完清除,为下一次读取准备
四、文件写入
1.默认打开文件写入,都是开头写,会覆盖原文件开头的
int res=0;
res=fwrite(str_msg,sizeof(char),strlen(str_msg),fp);//可以返回写入的字节数2.一行行写入
fputs(ch,fp);将字符(ch的值)输出到fp所指向的文件中去
五、二进制文件
1.初始化结构体:
PRODUCT_T product_info={1001,"电脑",5930.8};
PRODUCT_T product_other={1002,"奶茶",20.5};2.打开文件及其写入:
//w+打开二进制文件会清空文件里的内容,所以只适合文件不存在时使用//最好先rb+,如果打开失败,在调用wb+
fp=fopen("d:/desktop/product_info.dat","rb+");
if(fp==NULL)
{
fp=fopen("d:/desktop/product_info.dat","wb+");
}
fwrite(&product_info,sizeof(PRODUCT_T),1,fp);
fwrite(&product_other,sizeof(PRODUCT_T),1,fp);
一定要注意,读和写要分开进行
//文件写入读取要分开,关闭文件
close(fp);//再次打开文件后读取内容
fp=fopen("d:/desktop/product_info.dat","rb+");
读取文件内容
while(fread(&product_msg,sizeof(PRODUCT_T),1,fp))
{
printf("product_id=%d\n",product_msg.product_id);
printf("product_name=%s\n",product_msg.product_name);
printf("product_price=%f\n",product_msg.price);
memset(&product_msg,0,sizeof(PRODUCT_T));}
六、文件定位函数
1. rewind(FILE * fp):使文件位置指针重新至于文件开头
2. ftell(FILE *fp):返回文件位置指针的当前值
3. fseek (FILE *fp, long int offset, int origin): 改变文件位置指针的位置offset:偏移量 orgin:搜索的起始位置
orgin的值:
SEEK_SET或0:文件开始
SEEK_CUR或1:当前文件指针位置
SEEK_END或2:文件末尾
#include<stdio.h>
int test1()
{
FILE *file,*newfile;
char buffer[40];
int bytes;
file=fopen("d:/desktop/chen.txt","r");
if(file==NULL)
{
printf("文件打开失败!\n");
return -1;
}
newfile=fopen("d:/desktop/newchen.txt","w");
if(newfile==NULL)
{
printf("文件打开失败!\n");
return -1;
}
while(bytes=fread(buffer,sizeof(char),40,file))
{
if(fwrite(buffer,sizeof(char),bytes,newfile)!=bytes)
{
printf("写入文件错误!\n");
fclose(file);
fclose(newfile);
return -1;
}
}
fclose(file);
fclose(newfile);
printf("文件拷贝成功!\n");
return 0;
}
int test2()
{
FILE *file,*newfile;
char buffer[40];
int read_size;
file=fopen("d:/desktop/chen.txt","r");
if(file==NULL)
{
printf("第一个文件打开失败!\n");
return -1;
}
newfile=fopen("d:/desktop/newchen.txt","a");
if(newfile==NULL)
{
printf("第二个文件打开失败!\n");
return -1;
}
while(read_size=fread(buffer,1,sizeof(buffer),file))
{
if(fwrite(buffer,1,read_size,newfile)!=read_size)
{
printf("文件写入失败!\n");
fclose(file);
fclose(newfile);
return -1;
}
}
fclose(file);
fclose(newfile);
printf("文件添加成功!\n");
return 0;
}
typedef struct
{
int product_id;
char product_name[20];
float price;
}PRODUCT_T;
int main()
{
test1();//文件里面的内容全部拷贝到一个新文件
test2();//在已经存在的文件的尾部写入内容
int i;
PRODUCT_T product_info={1001,"电脑",5930.8};
PRODUCT_T product_other={1002,"奶茶",20.5};
PRODUCT_T product_msg={0};
FILE *fp=NULL;
char buffer[40]={0};
int res=0;
//w+打开二进制文件会清空文件里的内容,所以只适合文件不存在时使用
//最好先rb+,如果打开失败,在调用wb+
fp=fopen("d:/desktop/product_info.dat","rb+");
if(fp==NULL)
{
fp=fopen("d:/desktop/product_info.dat","wb+");
}
fwrite(&product_info,sizeof(PRODUCT_T),1,fp);
fwrite(&product_other,sizeof(PRODUCT_T),1,fp);
//文件写入读取要分开,关闭文件
close(fp);
//再次打开文件后读取内容
fp=fopen("d:/desktop/product_info.dat","rb+");
while(fread(&product_msg,sizeof(PRODUCT_T),1,fp))
{
printf("product_id=%d\n",product_msg.product_id);
printf("product_name=%s\n",product_msg.product_name);
printf("product_price=%f\n",product_msg.price);
memset(&product_msg,0,sizeof(PRODUCT_T));
}
/* if(fp==NULL)
{
fp=fopen("d:/desktop/product_info.dat","wb+");
}
//如果用记事本打开二进制文件是看不到内容的
for(i=0;i<5;i++)
{
res=fwrite(&product_info,sizeof(PRODUCT_T),1,fp);
// res=fwrite(&product_other,sizeof(PRODUCT_T),1,fp);
}
if(res==NULL)
{
printf("结构体写入失败!\n");
return -1;
}*/
close(fp);
return 0;
}