C语言相关知识——文件操作

C语言相关知识——文件操作

1.概述

  • 什么是文件

    文件是保存在外存储器上(一般代指磁盘,也可以是优盘,移动硬盘)的数据集合。

  • 文件操作体现在哪几个方面

    1. 文件内容的读取
    2. 文件内容的写入

    数据的读取和写入可被视为针对文件输入和输出的操作,此时数据就像水流一样从外存储器流向内存,或者从内存流向外存储器,所以系统形象的文件操作为文件流。

    C语言程序对文件的操作采用“文件缓冲机制”。就是说在程序中对文件的数据读写并不是直接操作文件中的数据,而是系统会为文件在内存中创建“文件缓冲区”。程序对文件的操作,其实是在缓冲区进行的。

2.文件分类

根据数据的存储方式划分:

  1. 文本文件(ASCLL文件)
  2. 二进制文件
  • 文件标识

    1. 文件系统中:路径+文件名,举例:d:/aaa/bbb.txt;
    2. C语言程序中:文件指针(文件类型指针),语法:FILE *指针变量名
  • 文件操作步骤:

    1. 打开文件
    2. 文件处理(读写文件)
    3. 关闭文件

2.文件的操做

  • 打开文件,让系统为文件创建文件缓冲区

    • 函数名:fopen

    • 头文件:#include

    • 函数原型:函数名,函数参数列表(形参),函数返回值类型

      FILE* fopen(const char *path,const char *mode);

    • 函数的功能:打开文件,并为文件创建缓冲区

    • 函数参数:

      • path:目标文件的路径
      • mode:文件打开的方式(读,写,读写)
    • 返回值:

      • 成功:返回文件指针File* (缓冲区首地址)
      • 失败:返回NULL
  • 文件的关闭,文件使用完毕,一定要记得释放

    • 函数名:fclose
    • 头文件: #include
    • 函数原型:int fclose(FILE* fp);
    • 函数的功能:关闭文件,释放缓冲区
    • 函数参数:
      • fp:已经打开的文件指针
    • 返回值:
      • 成功:返回0
      • 失败:返回EOF(-1)
  • 文件打开与关闭案例

    //文件的打开与关闭
    #include 
    
    int main(int argc,char* argv)
    {
    	//在命令行执行./a.out的时候,传递一个需要打开的目标文件地址
        if(argc < 2)
        {
            printf("输入有误,请按照<%s文件路径>格式输入\n",argv[0]);
            return -1;
        }
        //根据提供的文件路径,打开文件
        FILE* fp = fopen(argv[1],"r");
        //校验文件是否成功
        if(!fp)
        {
            perror("文件打开失败!");
            return -1;
        }
        puts("文件打开成功!")//关闭打开的文件
        int ret = fclose(fp);
        //校验文件是否关闭成功(很多时候这一步会省略掉)
        if(ret == -1)
        {
            perror("文件关闭失败!");
            return -1;
        }
        puts("文件关闭成功!");
        
        return 0;
    }
    

3.文件读写

单字符读写

  • 函数名:fgets
  • 头文件:#include
  • 函数原型:int fgets(File* fp);
  • 函数的功能:从fp代表的文件中获取一个字符
  • 函数参数:
    • fp:我们需要操作的文件的描述
  • 返回值:
    • 成功:返回读取到的字符
    • 失败:或者文件末尾,返回EOF(-1)

方式一

//单字符的读取
#include 

int main(int argc,char **argv)
{
    if(argc < 2)
    {
        printf("输入有误,请按照<%s文件路径>格式输入\n",argv[0]);
        return -1;
    }
    //打开文件
    FILE* fp = fopen(argv[1],"r");
    //非空校验
    if(!fp)
    {
        perror("文件打开失败!");
    }
    //单字符读取文件
    int re = fgetc(fp);
    if(re == -1)
    {
        perror("文件读取失败!");
        return -1;
    }
    /*循环单字符输出文件内容
    while(re == -1 && re != '\n')
    {
    	re = fgets(fp);
    }
    */
    printf("%c\n",re);
    //关闭文件
   	fclose(fp);
    
    return 0;
}

方式二

//单字符读取
#include 
int main(int argc,char **argv)
{
    if(arge<2)
    {
        printf("输入有误,请按照<%s文件路径>格式输入\n",argv[0]);
        return -1;
    }
    //打开文件
    FILE* fp=fopen(argv[1],"r");
    
    if(!fp)
    {
        perror("打开文件失败!")
        return -1;
    }
    char ch;
    while((ch = fgets(fp))!=EOF)
    {
        printf("%c",ch);
    }
    fclose(fp);
    
    return 0;
}

多字符

  • 函数名:fgets()
  • 头文件:#include
  • 函数原型:char *fgets(char *buf,int size,FILE *fp)
  • 函数功能:从fp代表文件中获取size个字符,放置在buf代表的内存中。
  • 函数参数:
    • buf:内存空间首地址用于存放读取的字节
    • size:待读取的字符,实际读取size-1
    • fp:已经打开的文件指针
  • 返回值:
    • 成功:返回buf
    • 失败:文件末尾,返回NULL

案例

//多字符读取
#include 
int main(int argc,char **argv)
{
    if(arge<2)
    {
        printf("输入有误,请按照<%s文件路径>格式输入\n",argv[0]);
        return -1;
    }
    FILE* fp = fopen(argv[1],"rw");
    
    if(!fp)
    {
        perror("文件打开失败!");
        return -1;
    }
    //多字符文件读取
    //创建缓冲区大小
    char buf[64] = {0};
    while(fgets(buf,64,fp)!=NULL)
    {
        printf("%s",buf);
        //给buf赋初值
        memset(buf,0,sizeof(buf));
    }
    printf("\n");
    
    fclose(fp);
    
    return 0;
}

单字符写入

  • 函数名:fputs
  • 头文件:#include
  • 函数原型:int fput(int c,FILE* fp)
  • 函数功能:向fp代表的文件中写入一个字符c
  • 函数参数:
    • c:待写入的字符
    • fp:已打开的文件指针
  • 返回值:
    • 成功:返回字符c
    • 失败:返回EOF(-1)

多字符写入

  • 函数名:fputs
  • 头文件:#include
  • 函数原型:int fputs(const char *s,FILE *fp);
  • 函数功能:向fp代表的文件中写入一个字符数组s
  • 函数参数:
    • s:待写入的字符数组(写入缓冲区)
    • fp:已打开的文件指针
  • 返回值:
    • 成功:返回非负整数(>0)
    • 失败:返回EOF(-1)

案例:

//多字符写入
#include 

int main(int argc,char **argv)
{
    if(argc<3)
    {
     printf("输入有误,请按照<%s文件路径>格式输入\n",argv[0]);
        return -1;
    }
    FILE* fp = fopen(argv[1],"w");
    
    if(!fp)
    {
        perror("文件打开失败!");
        return -1;
    }
    
    //单字符写入
    
    fputs(argv[2],fp);
    
    fclose(fp);
    
    return 0;
    
}

判文件结束

  • 函数名:feof(fp)

  • 头文件:#include

  • 函数原型:int feof(fp)

  • 函数功能:在读fp指向的文件时判断是否遇到文件结束

  • 函数参数:

    • fp:已打开的文件指针
  • 返回值:

    • 文件未读取完毕:返回0
    • 文件读取完毕:返回非0
  • 练习:实现一个文本文件的拷贝

/**
* feof案例:将一个磁盘文件中的信息复制到另一个磁盘文件中。
*/
#include 
#include 
int main(int argc,char** argv)
{
// main函数输入判断
	if(argc < 3)
	{
		printf("输入有误,请按照<%s 源文件路径 目标文件路径>格式输入\n",argv[0]);
		return -1;
    }
    // 打开文件
	FILE* in = fopen(argv[1],"r");
    FILE* out = fopen(argv[2],"w");
    // 校验
	if(!in || !out)
	{
		perror("文件打开失败!");
		return -1;
	}
	// 单个字符读写
	// while(!feof(in))
	// {
	// 读写操作
	// fputc(fgetc(in),out);
	//}
	// 多个字符读写
	// 创建一个缓冲区,用来存放读写的数据
	char buf[64] = {0};
	// 使用循环读写文件
	while(fgets(buf,64,in)!=NULL)
	{
		// 写入数据
   		fputs(buf,out);
    	// 重置缓冲区
    	memset(buf,0,sizeof(buf));
    }
    printf("\n");
    //关闭文件
    fclose(in);
    fclose(out);
}
  • fread
    • 头文件:#include
    • 函数原型:size_t fread(void *ptr,size_t size,size_t count,FILE *fp)
    • 函数功能:从fp代表的文件中以size为单位(一个数据块)读取count个数据块放在ptr内存中。
    • 函数参数:
      • ptr:内存空间首地址,用于存放读取到数据(缓冲区)
      • size:数据块大小,以byte为单位
      • count:待读取的数据块的个数
      • fp:已打开的文件指针
    • 返回值:
      • 成功:返回实际写入的字节数
      • 失败:返回<0

案例:

/**
* 数据库读写案例:从键盘输入4个学生的有关数据,然后把它们转存到磁盘文件上去。
*/
#include 
#define SIZE 4 // 学生数量
// 创建学生结构体
struct Student
{
	char name[20];
	int num;
	int age;
	char addr[50];// 住址
} stud[SIZE];
// 保存学生信息到文件
void save()
{
	FILE* fp;
    int i;
    if((fp = fopen("stu-list","wb")) == NULL)// stu-list对应的目录:./stu-list,wb-二进制写
入,默认是文本写入
	{
		perror("文件打开失败!");
		return;
	}
// 写入操作
	for(i = 0; i < SIZE; i++)
	{
		fwrite(&stud[i],sizeof(struct Student),1,fp);
	}
// 关闭文件
	fclose(fp);
}
void main()
{
	int i;
	printf("请输入学生的信息:姓名,学号,年龄,住址\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();
	}
}

文件的随机读写

  • 说明:C语言允许程序员在读写文件内容时,可在指定的位置上读写数据
  • 文件随机读写的核心操作: 文件位置指针的定位
  • 文件位置指针的移动方法:
    • rewind
      • 头文件:#include
      • 函数原型:void rewind(FILE* fp);
      • 函数功能: 将文件位置指针定位到文件开头
      • 函数参数:
        • fp:已经打开的文件指针
      • 返回值:无
    • fseek
      • 头文件:#include
      • 函数原型:int fseek(FILE *fp, long offset, int whence);
      • 函数功能:将文件位置指针定位到指定位置
      • 函数参数:
        • fp: 已经打开的文件指针
        • offset: 相对于参考位置的偏移位置
        • whence: 参考位置
          • SEEK_SET 或 0 表示文件头
          • SEEK_CUR 或 1 表示当前读写的位置
          • SEEK_END 或 2 表示文件尾
      • 返回值:
        • 成功:0
        • 失败:-1
    • ftell
      • 头文件:#include
      • 函数原型:long ftell(FILE *fp)
      • 函数功能:获取文件位置指针当前位置
      • 函数参数:
        • fp:已经打开的文件指针
      • 返回值:
        • 成功文件位置指针当前位置
        • 失败:-1

案例1:

/**
* 有一个磁盘文件,第一次将它的内容显示在屏幕上,第二次把它复制到另一文件上。
*/
#include 
void main()
{
	FILE *fp1, *fp2;
	fp1 = fopen("file1.c", "r");
	fp2 = fopen("file2.c", "w");
	while (!feof(fp1))
		putchar(getc(fp1)); /*输出到屏幕*/
	rewind(fp1); /*位置指针返回到文件头*/
	while (!feof(fp1))
		putc(getc(fp1), fp2); /*从文件file1的头读起,输出到文件file2中*/
	fclose(fp1);
	fclose(fp2); /*关闭文件*/
}

案例2:

/**
* 在磁盘文件上存有10个学生的数据。要求将第1、3、5、7、9个学生数据输入计算机,并在屏幕上显示出来。
*/
#include 
#include 
struct student_type
{
	char name[10];
	int num;
	int age;
	char sex;
} stud[10];
void main()
{
	int i;
    FILE *fp;
    if ((fp = fopen("stud-dat", "rb")) == NULL)
	{
		printf("can not open file\n");
		return;
	}
	for (i = 0; i < 10; i += 2)
	{
		fseek(fp, i * sizeof(struct student_type), 0);
		fread(&stud[i], sizeof(struct student_type), 1, fp);
		printf("%s %d %d %c\n", stud[i].name, stud[i].num, stud[i].age, 				stud[i].sex);
	}
	fclose(fp);
}

案例3:

/**
* 下列C程序的功能是,用“追加”的形式打开文件gg.txt,查看文件读写指针的位置,然后向文件写入“data”,
再查看
文件读写指针的位置。
*/
#include "stdio.h"
main()
{
	long p;
	FILE *fp;
	if ((fp = fopen("gg.txt","a")) == NULL)
	{
		printf("cannot open this file!\n");
		return;
    }
    p = ftell(fp);
	printf("p=%ld\n",p);
	fputs("data", fp);
	p = ftell(fp);
	printf("p=%ld\n",p);
	fclose(fp);
}

你可能感兴趣的:(c语言,开发语言)