文件操作
/*
1---文件:文件是存储在外部介质上的数据的集合
高级文件操作:有缓冲区的文件操作 1M
低级文件操作:非缓冲区操作,缓冲区大小有程序决定
文件的分类:
①从文件组织形式角度:ASCII文件、二进制文件
②从是否引用缓冲区角度:缓冲、非缓冲文件
③从存取文件方式角度:顺序存取文件、随机存取文件
2---C语言操作文件主要有以下3个基本步骤:
①打开文件
②读写数据
③关闭文件
3---文件类型指针 FILE *
typedef struct
{
char fd; //文件描述符(file defination)
unsigned char *buf; //缓冲区
size_t bsize; //缓冲区大小
unsigned char *p; //当前的指向
short level; //缓冲区满或空
unsigned short flags; //文件状态标记
.........
}FILE;
文件类型(结构体)——FILE类型 :
FILE类型是一种结构体类型,在stdio.h中定义,用于存放文件的当前的有关信息。
文件指针: 对文件的访问是通过FILE类型指针变量(简称:文件指针)来完成的。
*/
#include <stdio.h>
int main(void)
{
return 0;
}
fopen()函数
/*
fopen
语法:
#include <stdio.h>
FILE *fopen( const char *fname, const char *mode );
fopen()函数打开由fname(文件名)指定的文件, 并返回一个关联该文件的流.如果发生错误, fopen()返回NULL. mode(方式)是用于决定文件的用途(例如 用于输入,输出,等等)
Mode(方式) 意义
r 读
w 写
a 追加
b 二进制
"r" 打开一个用于读取的文本文件
"w" 创建一个用于写入的文本文件,若原文件存在,则删除原文件并创建新文件,慎用
"a" 附加到一个文本文件,不删除原文件,打开时文件指针指向文件末尾
"b" 二进制文件
"rb" 打开一个用于读取的二进制文件
"wb" 创建一个用于写入的二进制文件
"ab" 附加到一个二进制文件
"r+" 打开一个用于读/写的文本文件, 需要更改文件状态进行读写转换
"w+" 创建一个用于读/写的文本文件
"a+" 打开一个用于读/写的文本文件
"rb+" 打开一个用于读/写的二进制文件
"wb+" 创建一个用于读/写的二进制文件
"ab+" 打开一个用于读/写的二进制文件
示例:
char ch;
FILE *input = fopen( "stuff", "r" );
ch = getc( input );
int fclose(FILE *stream);
关闭一个流。
成功返回0;失败是返回EOF。
int fcloseall(void);
关闭所有打开的流,除了stdin,stdout,stdprn,stderr和stdaux。
*/
#include <stdio.h>
int main(void)
{
FILE *fp=NULL;
char ch,filename[50];
printf("Please input file`s name!\n");
gets(filename);
fp=fopen(filename,"r");//r要求文件必须存在且可读
ch=fgetc(fp);
while (ch!=EOF) {//EOF在系统中表示-1,指向最后一个字符的下一个,是文件结束标记
putchar(ch);
ch=fgetc(fp);
}
fclose(fp);//释放申请的文件对象,清空缓冲区在缓冲区未满的情况下做最后处理工作,
return 0;
}
fgetc、fputc函数
/*
fgetc
int fgetc(FILE *stream);
从流中读取下一个字符。
成功是返回输入流中的下一个字符;至文件结束或出错时返回EOF。
fputc
#include <stdio.h>
int fputc( int ch, FILE *stream );
函数fputc()把给出的字符ch写到给出的输出流. 返回值是字符, 发生错误时返回值是EOF.
perror
语法:
#include <stdio.h>
void perror( const char *str );
perror()函数打印str(字符串)和一个相应的执行定义的错误消息到全局变量errno中.
*/
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *pf=fopen("test","w");
if (pf==NULL) {
perror("test error\n");
exit(1);
}
char c;
while (1) {
scanf("%c",&c);
if (c=='q') {
break;
}
fputc(c,pf);
}
fclose(pf);
return 0;
}
文件拷贝
/*
实现文件拷贝
*/
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char ch,infile[50],outfile[50];
FILE *in=fopen(infile,"r");
FILE *out=fopen(outfile,"w");
printf("Enter the infile name:\n");
scanf("%s",infile);
printf("Enter the outfile name:\n");
scanf("%s",outfile);
if (in==NULL) {
perror("Cannot open infile:\n");
exit(1);
}
if (out==NULL) {
perror("Cannot open outfile:\n ");
exit(1);
}
ch=fgetc(in);
while (ch!=EOF) {
fputc(ch,out);
ch=fgetc(in);
}
fclose(in);
fclose(out);
}
将文件写入磁盘文件
/*
实现文件拷贝
将文件写入磁盘文件
*/
#include <stdio.h>
int main(void)
{
FILE *fw=fopen("document","w");
char str[128]="hello itany";
int i=0;
while (i++<5) {
fputs(str,fw);
fputs("\n",fw);
}
fclose(fw);
return 0;
}
#include <stdio.h>
int main(void)
{
FILE *fp;
char ch,filename[50];
printf("Please input filename:\n");
scanf("%s",filename);
if ((fp=fopen(filename,"w"))==NULL) {
printf("Cannot open file\n");
exit(0);
}
ch=getchar();
while (ch!="#") {
fputc(ch,fp);
ch=getchar();
}
fclose(fp);
}
格式化文件读写函数
/*
格式化文件读写函数
fprintf( FILE *stream, const char *format, ... );
fscanf( FILE *stream, const char *format, ... );
与函数printf,scanf作用基本相同,
区别:
fprintf,fscanf读写的对象是磁盘文件,
printf,scanf读写的对象是终端
fprintf
#include <stdio.h>
int fprintf( FILE *stream, const char *format, ... );
fprintf()函数根据指定的format(格式)(格式)发送信息(参数)到由stream(流)指定的文件. fprintf()只能和printf()一样工作. fprintf()的返回值是输出的字符数,发生错误时返回一个负值.
char name[20] = "Mary";
FILE *out;
out = fopen( "output.txt", "w" );
if( out != NULL )
fprintf( out, "Hello %s\n", name );
fscanf
#include <stdio.h>
int fscanf( FILE *stream, const char *format, ... );
函数fscanf()以scanf()的执行方式从给出的文件流中读取数据. fscanf()的返回值是
事实上已赋值的变量的数,如果未进行任何分配时返回EOF.
*/
#include <stdio.h>
struct student
{
char name;
int age;
float score;
};
int main(void)
{
int i;
FILE *fr=fopen("1.txt","r");
fscanf(fr,"%d",&i);
printf("%d\n",i);
fclose(fr);
return 0;
}
int main1(void)
{
FILE *fw=fopen("1.txt","w");
fprintf(fw,"%d",123);
fclose(fw);
return 0;
}
fprintf、fprintf
/*
格式:
fprintf(fp,格式字符串,输出表列);
fprintf(fp,格式字符串,输入表列);
例如:
fprintf(fp,“%d,%f”,i,j);
其含义是:将整型变量i和实型变量j的值按照%d和%f的格式输出到fp指向的文件中。
fscanf(fp,“%d%f”,i,j);
其含义是:从fp所指向的文件中读取一个整型数据赋值给变量i,一个实型数据赋值给变量j。
*/
#include <stdio.h>
#include <string.h>
struct student
{
char name;
int age;
float score;
};
int main(void)
{
struct student a={'a',12,12};
FILE *fw=fopen("1.txt","w");
fprintf(fw,"%s %d %f",a.name,a.age,a.score);
fclose(fw);
//memset(void *dest,int ch,lenth);
memset(&a,0,sizeof(a));
FILE *fr=fopen("1.txt","r");
fscanf(fr,"%s %d %f",&a.name,&a.age,&a.score);
printf("%c: %d %f \n",a.name,a.age,a.score);
fclose(fr);
return 0;
}
读写二进制文件
/*
读写二进制文件
读写函数形式 :
int fread(void *buffer,int size,int count,FILE *fp);(缓冲区,大小,次数,)
从fr中读取num次每次size个字节,将读取的内容存入buf
int fwrite(void *buffer,int size,int count,FILE *fp);
说明:
buffer是指针,对fread用于存放读入数据的首地址;对fwrite是要输出数据的首地址。
size是一个数据块的字节数(每块大小),count是要读写的数据块块数。
fread、fwrite返回读取/写入的数据块块数
fwrite
#include <stdio.h>
int fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
fwrite()函数从数组buffer(缓冲区)中, 写count个大小为size(大小)的对象到stream(流)指定的流. 返回值是已写的对象的数量.
fread
#include <stdio.h>
int fread( void *buffer, size_t size, size_t num, FILE *stream );
函数fread()读取[num]个对象(每个对象大小为size(大小)指定的字节数),并把它们替换到由buffer(缓冲区)指定的数组. 数据来自给出的输入流. 函数的返回值是读取的内容数量...
使用feof()或ferror()判断到底发生哪个错误.
ferror
#include <stdio.h>
int ferror( FILE *stream );
ferror()函数检查stream(流)中的错误, 如果没发生错误返回0,否则返回非零. 如果发生错误, 使用perror()检测发生什么错误.
*/
#include <stdio.h>
int main1(void)
{
FILE *fr=fopen("1.txt","r");
int i=0;
fread(&i,4,1,fr);
printf("%d\n",i);
fclose(fr);
return 0;
}
int main(void)
{
FILE *fw=fopen("1.txt","w");
int i=0x61626364;
fwrite(&i,4,1,fw);
fclose(fw);
return 0;
}
文件定位
/*
文件定位
对文件的读写可以顺序读写,也可以随机读写。可以通过文件位置指针函数,实现文件的定位读写 。
13.4.1 rewind()函数
功能:使文件位置指针重返文件的开头。
格式:rewind(fp);
13.4.2 fseek()函数
功能:移动文件读写位置指针,以便文件的随机读写。
格式:fseek(FILE *fp,long offset,int whence);
说明:
①whence参数代表计算起始点(计算基准).计算基准可以是下面符号常量:
符号常量 值 含义
SEEK_SET 0 从文件开头计算
SEEK_CUR 1 从文件指针当前位置计算
SEEK_END 2 从文件末尾计算
说明:
②offset代表偏移量(单位:字节).从计算起始点 开始再偏移offset,得到新的文件指针位置。
offset为正,向后偏移;offset为负,向前偏移。
13.4.3 获取当前位置指针——ftell()函数
功能:得到文件当前位置指针的位置,此位置相对于文 件开头的。
格式:long ftell(FILE *fp);
返回值:就是当前文件指针相对文件开头的位置。
*/
/*
int fseek(FILE *stream,long offset,int whence);
在流上重新定位文件结构的位置。fseek设置与流stream相联系的文件指针到新的位置,新位置与whence给定的文件位置的距离为offset字节。
whence的取值必须是0,1或2中的一个,分别代表在stdio.h中定义的三个符号常量:
0是SEEK_SET,是文件开始位置;
1是SEEK_CUR,是当前的指针位置;
2时SEEK_END,是文件末尾。
调用了fseek之后,在更新的文件位置上,下一个操作可以是输入;也可以是输出。成功地移动了指针时,fseek返回0;出错或失败时返回非0值。
例:
*/
#include <stdio.h>
FILE *stream;
int main( void )
{
long l;
float fp;
char s[81];
char c;
stream = fopen( "fscanf.txt", "w+" );
if( stream == NULL ){
printf( "The file fscanf.out was not opened\n" );
}else{
fprintf( stream, "%s %ld %f%c", "a-string",65000, 3.14159, 'x' );
/* Set pointer to beginning of file: */
fseek( stream, 0L, SEEK_SET );
/* Read data back from file: */
fscanf( stream, "%s", s );
fscanf( stream, "%ld", &l );
fscanf( stream, "%f",
fscanf( stream, "%c", &c );/* Output data read: */
printf( "%s\n", s );
printf( "%ld\n", l );
printf( "%f\n", fp );
printf( "%c\n", c );
fclose( stream );
return 0;
}
}
文件读取
/*
读取文件
*/
#include <stdio.h>
int main(void)
{
FILE *fr=fopen("1.txt","r");
char buff[40]="";
while (1) {
fread(buff,30,1,fr);
if (feof(fr)!=0) {
break;
}
printf("%s",buff);
// for (int i=0; i<10; i++) {
// printf("%c",buff[i]);
// }
// memset(buff,0,sizeof(buf));
}
printf("\n");
fclose(fr);
return 0;
}
* 将视频文件从终端打开*
/*
将视频文件从终端打开
*/
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE *fr=fopen("/Users/student/Desktop/123.mp4","r");
FILE *fw=fopen("abc.mp4","w");
char buff[1024]="";
while (1) {
fread(buff,1024,1,fr);
if (feof(fr)!=0) {
break;
}
fwrite(buff,1024,1,fw);
memset(buff,0,sizeof(char[1024]));
}
fclose(fr);
fclose(fw);
return 0;
}
文件合并
/*
将文件分割成1M大小,将分割后的文件合并
*/
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE *fr=fopen("/Users/student/Desktop/123.mp4","r");
FILE *fw=fopen("/Users/student/Desktop/123_cpy.mp4","w");
if (fr==NULL||fw==NULL) {
perror("File open failure\n");
}
#define LEN 1024
char buff[LEN];
int len;
while (1) {
memset(buff,0,LEN);
len=fread(buff,1,LEN,fr);
if (feof(fr)!=0) {
break;
}
fwrite(buff,LEN,1,fw);
}
fwrite(buff,len,1,fw);
fclose(fr);
fclose(fw);
}
文件管理常用函数
/*
char *fcvt(double value,int ndig,int *dec,int *sign);
把浮点数转换成字符串,把浮点数value转换成长度为ndig的以空字符终结的字符串,返回一个指向这个字符串的指针,相对于串的开始处,
小数点的位置,由dec间接存贮,dec若为负值,表示小数点在返回的字符串的左边。返回的字符串本身不带小数点。如果value的符号为负,由sign指向的值非零;否则它是零。
FILE *fdopen(int handle,char *type);
把流与一个文件描述字相联系地打开。fdopen使流stream与一个从creat,dup,dup2或open得到的文件描述字相联系。流的类型type必须与打开文件描述字handle的模式相匹配。
类型字符串type可以是下列值之一:
r,打开用于只读;
w,创建用于写;
a,打开用于写在原有内容后面,文件不存在时创建用于写;
r+,打开已存在的文件用于更新(读和写);
a+,添加打开,文件不存在时创建,在末尾更新。成功时返回新打开的流。出错时返回NULL。
int feof(FILE *stream);
测试所给stream的文件尾标记的宏。
若检测到文件尾标记EOF或Ctrl-z返回非零值;否则,返回0。
#include
int ferror(FILE *stream);
测试给定流读写错误的宏。
若检测到给定流上的错误返回非0值。
struct ffblk {
char ff_reserved[21];
char ff_attrib;
unsigned ff_ftime;
unsigned ff_fdate;
long ff_fsize;
char ff_name[13];
};
int fflush(FILE *stream);
清除输入流的缓冲区,使它仍然打开,并把输出流的缓冲区的内容写入它所联系的文件中。成功时返回0,出错时返回EOF。
int fgetchar(void);
从标准输入流中读取字符,时定义为getc(stdin)的宏。
返回输入流stdin中的下一个字符,它已被转换成为无符号扩展的整形值。遇到出错或文件结束时返回EOF。
*/
#include <stdio.h>
int main(void)
{
FILE *fp=NULL;
char ch,filename[50];
printf("Please input file`s name!\n");
gets(filename);
fp=fopen(filename,"r");
ch=fgetc(fp);
while (ch!=EOF) {
putchar(ch);
ch=fgetc(fp);
}
fclose(fp);
return 0;
}