文件操作

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//读文本文件
int read(char filePath[]);
//写文本文件
int write(char filePath[]);
//读二进制文件
int bread(char filePath[]);
//写二进制文件
int bwrite(char filePath[]);
//文件拷贝
int copy(char filePath[]);
struct person{
    char name[128];
    int age;
};
int main(){
    char filePath[1024];
    strcpy(filePath,"temp.txt");
    //写文本文件
    write(filePath);
    printf("=========\n");
    //读文本文件
    read(filePath);
    printf("=========\n");

    strcpy(filePath,"temp.data");
    //写二进制文件
    bwrite(filePath);
    printf("=========\n");
    //读二进制文件
    bread(filePath);
    printf("=========\n");

    //文件定位函数
    //long ftell(FILE *file)返回当前文件定位指针的位置
    //void rewind(FILE *file)将文件定位指针的位置重置到文件开始
    //int fseek(FILE *file,long offset,int origin)将文件定位指针的位置移动到任意指定位置,移动超出文件定位指针开始位置返回-1,其他情况都返回0
    //file表示文件结构体指针;
    //offset表示偏移量,正数表示向后移,负数表示向前移,最终定位位置不会超出文件的开始和文件的末尾,单位为字节
    //origin表示移动时的参考位置,0:文件开头,1:当前位置,2:文件末尾

    strcpy(filePath,"temp.txt");
    FILE *file = fopen(filePath,"w+");
    printf("当前的文件定位指针:%d\n",ftell(file));
    //写入一行字符串
    fprintf(file,"写入一行字符串\n");
    printf("写入字符串后的文件定位指针:%d\n",ftell(file));
    //重置文件指针
    rewind(file);
    printf("重置后的文件定位指针:%d\n",ftell(file));
    //读取一行字符串
    char buf[1024];
    fgets(buf,1024,file);
    printf("读取到的内容:%s\n",buf);
    printf("读取文件后的文件定位指针:%d\n",ftell(file));
    //将文件定位指针移向开始,再读一行字符串
    int count = fseek(file,-23,1);
    printf("count=%d\n",count);
    printf("重置后的文件定位指针:%d\n",ftell(file));
    // fgets(buf,1024,file);
    // memset(buf,0,sizeof(buf));
    void *p = fgets(buf,1024,file);
    printf("p=%p\n",p);
    printf("读取到的内容:%s\n",buf);
    printf("读取文件后的文件定位指针:%d\n",ftell(file));
    //文件拷贝
    copy(filePath);

    //stdin:标准输入,在Linux系统上使用0表示,标准输入就是键盘
    //stdout:标准输出,在Linux系统上使用1表示,标准输出就是显示器
    //stderr:标准错误输出,在Linux系统上使用2表示,标准错误输出就是显示器
    //使用文件操作从标准输出获取输入
    fgets(buf,1024,stdin);
    //使用文件操作向标准输出输出内容
    fprintf(stdout,"标准输入输入的内容是:%s\n",buf);
    //使用文件操作向标准错误输出输出内容
    fprintf(stderr,"标准输入输入的内容是:%s\n",buf);
    return 0;
}




//文件拷贝
int copy(char filePath[]){
    //打开文件
    FILE *in = fopen(filePath,"rb");
    FILE *out = fopen("out","wb");
    //按缓冲区大小进行拷贝,有bug,会导致少拷贝或者多拷贝数据
    // char buf[1024];
    // int count = 0;
    // do{
    //     count = fread(buf,1024,1,in);
    //     fwrite(buf,1,count,out);
    //     fflush(out);
    //     bzero(buf,sizeof(buf));
    // }while(count != 0);

    //按字节进行拷贝,完美拷贝,但是一次只拷贝一个字节太慢了
    char c = -1;
    while((c = fgetc(in))!=-1){
        fputc(c,out);
    }
    //关闭文件
    fclose(in);
    fclose(out);
    in = 0;
    out = 0;
    return 0;
}

打开文件和关闭文件

  • 打开文件

    • 函数原型:FILE *fopen(const char *filePath,const char *mode)
    • 返回值为文件指针
    • filePath:表示文件的路径
    • mode:表示打开文件的方式
  • mode参数详解

    • r:表示读一个文件,是read的简写
    • w:表示写一个文件,是write的简写
    • a:表示追加写入,是append的简写
    • 后缀"t"表示文件文件,是text的简写,打开文本文件可以省略后缀"t"
    • 后缀"b"表示二进制文件,是binary的简写,打开二进制文件一定要使用后缀"b"显示指定使用二进制的方式打开文件
    • +:表示使用读写的方式打开文件,即文件可读也可写
    • mode参数对照表
    mode含义备注
    rt以读的方式打开文本文件文件不存在会报错
    wt以写的方式打开文本文件文件不存在就创建文件
    at以追加写入的方式打开文本文件文件不存在就创建文件
    rb以读的方式打开二进制文件文件不存在会报错
    wb以写的方式打开二进制文件文件不存在就创建文件
    ab以追加写入的方式打开二进制文件文件不存在就创建文件
    rt+以读写的方式打开文本文件,在读的基础上可以写入文件不存在会报错
    wt+以读写的方式打开文本文件,在写的基础上可以读取文件不存在就创建文件
    at+以读写的方式打开文本文件,在追加的基础上可以读取文件不存在就创建文件
    rb+以读写的方式打开二进制文件,在读的基础上可以写入文件不存在会报错
    wb+以读写的方式打开二进制文件,在写的基础上可以读取文件不存在就创建文件
    ab+以读写的方式打开二进制文件,在追加的基础上可以读取文件不存在就创建文件
  • 关闭文件

    • 函数原型:int fclose(FILE *file)

读文本文件

  • 函数原型
    1. 读一个字符:char fgetc(FILE *file)
    2. 读一行字符:cahr *fgets(char *buf,int size,FILE *file)
      • 读取的字符个数为 size-1,最多读取一行
      • 返回值为读取缓冲区的收地址指针
      • 失败或读到文件末尾返回空(0)
    3. 格式化读取:fscanf(FILE *file,const char *format,...)
  • 示例代码
int read(char filePath[]){
    FILE *file = fopen(filePath,"r");
    if(file != 0){
        printf("打开文件成功\n");
    }else{
        printf("打开文件失败\n");
        return -1;
    }
    //读文件
    //读文件的函数有
    //char fgetc(FILE *file);
    //fgets函数的作用,读取的字符个数为 size-1,最多读取一行,返回值为读取缓冲区的收地址指针,失败或读到文件末尾返回空(0)
    //cahr *fgets(char *buf,int size,FILE *file);
    //fscanf(FILE *file,const char *format,...);
    char content[1024];
    void *pointer = fgets(content,1024,file);
    // strcpy(content,fgets(content,1024,file));
    printf("fgets函数的返回值:%s\n",pointer);
    printf("读取文件内容成功,文件内容是:%s",content);
    printf("内容的长度:%d\n",strlen(content));
    //关闭文件,fclose(FILE *filePointer);
    fclose(file);
    file = 0;
    printf("关闭文件成功\n");
    return 0;
}

写文本文件

  • 函数原型
    1. 写一个字符:fputc(char c,FILE *file)
    2. 写一行字符:(char *str,FILE *file)
    3. 格式化写入:int fprintf(FILE *file,const char *format,...)
  • 实例代码
int write(char filePath[]){
    //打开文件,FILE *fopen(const char *filePath,const char *mode),filePath表示文件的路径,mode表示打开文件的方式,成功返回文件结构体的指针,失败返回0

    //r:只读;w:只写;a:追加;
    //t后缀表示文本文件,b表示二进制文件
    //rt:以文本文件的格式只读打开;rb:以二进制文件的格式只读打开;

    //以读写的方式打开文件
    //以写的方式打开文件会将文件清空,读和追加的方式则不会
    // FILE *file = fopen(filePath,"wt+");
    FILE *file = fopen(filePath,"w");
    if(file != 0){
        printf("打开文件成功\n");
    }else{
        printf("打开文件失败\n");
        return -1;
    }
    //写文件
    //写文件的函数有
    //fputc(char c,FILE *file);
    //fputs(char *str,FILE *file);
    //int fprintf(FILE *file,const char *format,...);
    int count = fprintf(file,"向文件输出一行字符串\n");
    printf("fprintf函数的返回值:%d\n",count);
    count = fprintf(file,"向文件输出一行字符串\n");
    printf("fprintf函数的返回值:%d\n",count);
    printf("向文件输出内容成功\n");

    fclose(file);
    file = 0;
    printf("关闭文件成功\n");
    return 0;
}

读二进制文件

  • 函数原型fread(char *buf,int size,int number,FILE *file)
  • 返回实际读取的字节数,失败或者读到文件末尾返回空(0)
  • buf:表示缓冲区指针
  • size:表示一个块多少个字节(一般填1)
  • number:表示多少个块
  • file:文件地址指针
  • 示例代码
//读二进制文件
int bread(char filePath[]){
    //以读二进制文件的方式打开文件
    FILE *file = fopen(filePath,"rb");
    if(file != 0){
        printf("打开文件成功\n");
    }else{
        printf("打开文件失败\n");
        return -1;
    }
    char buf[1024];
    memset(buf,0,sizeof(buf));
    //fread(char *buf,int size,int number,FILE *file)
    //返回实际读取的字节数,失败或者读到文件末尾返回空(0)
    //buf表示缓冲区,size表示一个块多少个字节(一般填1),number表示多少个块,file文件地址指针
    int count = fread(buf,1,45,file);
    printf("读取到的字节数:%d,读取到的内容:%s\n",count,buf);
    //读取保存的结构体
    struct person *per = malloc(sizeof(struct person));
    fread(per,sizeof(struct person),1,file);
    printf("读取到结构体的内容,姓名:%s,年龄:%d\n",per->name,per->age);
    fclose(file);
    file = 0;
    return 0;
}

写二进制文件

  • 函数原型:int fwrite(void *pointer,int size,int number,FILE *file)
  • 返回写入的字节数
  • pointer:表示起始地址的指针
  • size:表示数据块的字节数(一般填1)
  • number:表示写入的数据块
  • file:表示文件结构体指针
  • 示例代码
struct person{
    char name[128];
    int age;
};
//写二进制文件
int bwrite(char filePath[]){
    //以写二进制文件的方式打开文件
    FILE *file = fopen(filePath,"wb");
    if(file != 0){
        printf("打开文件成功\n");
    }else{
        printf("打开文件失败\n");
        return -1;
    }
    //int fwrite(void *pointer,int size,int number,FILE *file)
    //返回写入的字节数
    //pointer表示起始地址的指针,size表示数据块的字节数(一般填1),number表示写入的数据块,file表示文件结构体指针
    char content[1024];
    strcpy(content,"以写二进制文件的方式写入字符串");
    //写字符串
    int count = fwrite(content,1,strlen(content),file);
    printf("fwrite函数的返回值:%d\n",count);
    struct person p = {"杨逸",18};
    //写结构体
    count = fwrite(&p,1,sizeof(p),file);
    printf("fwrite函数的返回值:%d\n",count);
    printf("写二进制文件成功\n");

    fclose(file);
    file = 0;
    return 0;
}

文件定位指针操作

  • 获取当前文件定位指针的位置
    • 函数原型:long ftell(FILE *file)
  • 将文件定位指针的位置重置到文件开始
    • 函数原型:void rewind(FILE *file)
  • 将文件定位指针的位置移动到任意指定位置,移动超出文件定位指针开始位置返回-1,其他情况都返回0
    • 函数原型:int fseek(FILE *file,long offset,int origin)
    • file:表示文件结构体指针
    • offset:表示偏移量,正数表示向后移,负数表示向前移,最终定位位置不会超出文件的开始和文件的末尾,单位为字节
    • origin:表示移动时的参考位置,0:文件开头,1:当前位置,2:文件末尾
  • 示例代码
int main(){	
    	//文件定位函数
        //long ftell(FILE *file)返回当前文件定位指针的位置
        //void rewind(FILE *file)将文件定位指针的位置重置到文件开始
        //int fseek(FILE *file,long offset,int origin)将文件定位指针的位置移动到任意指定位置,移动超出文件定位指针开始位置返回-1,其他情况都返回0
        //file表示文件结构体指针;
        //offset表示偏移量,正数表示向后移,负数表示向前移,最终定位位置不会超出文件的开始和文件的末尾,单位为字节
        //origin表示移动时的参考位置,0:文件开头,1:当前位置,2:文件末尾

        strcpy(filePath,"temp.txt");
        FILE *file = fopen(filePath,"w+");
        printf("当前的文件定位指针:%d\n",ftell(file));
        //写入一行字符串
        fprintf(file,"写入一行字符串\n");
        printf("写入字符串后的文件定位指针:%d\n",ftell(file));
        //重置文件指针
        rewind(file);
        printf("重置后的文件定位指针:%d\n",ftell(file));
        //读取一行字符串
        char buf[1024];
        fgets(buf,1024,file);
        printf("读取到的内容:%s\n",buf);
        printf("读取文件后的文件定位指针:%d\n",ftell(file));
        //将文件定位指针移向开始,再读一行字符串
        int count = fseek(file,-23,1);
        printf("count=%d\n",count);
        printf("重置后的文件定位指针:%d\n",ftell(file));
        // fgets(buf,1024,file);
        // memset(buf,0,sizeof(buf));
        void *p = fgets(buf,1024,file);
        printf("p=%p\n",p);
        printf("读取到的内容:%s\n",buf);
        printf("读取文件后的文件定位指针:%d\n",ftell(file));
}

标准输入,标准输出和错误输出

  • stdin:标准输入,在Linux系统上使用0表示,标准输入就是键盘
  • stdout:标准输出,在Linux系统上使用1表示,标准输出就是显示器
  • stderr:标准错误输出,在Linux系统上使用2表示,标准错误输出就是显示器
  • 示例代码
int main(){
	//stdin:标准输入,在Linux系统上使用0表示,标准输入就是键盘
    //stdout:标准输出,在Linux系统上使用1表示,标准输出就是显示器
    //stderr:标准错误输出,在Linux系统上使用2表示,标准错误输出就是显示器
    //使用文件操作从标准输出获取输入
    fgets(buf,1024,stdin);
    //使用文件操作向标准输出输出内容
    fprintf(stdout,"标准输入输入的内容是:%s\n",buf);
    //使用文件操作向标准错误输出输出内容
    fprintf(stderr,"标准输入输入的内容是:%s\n",buf);
}