C语言学习笔记(十四) -文件管理 File Manager

文件操作

/*

 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的取值必须是012中的一个,分别代表在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;
}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值