什么是文件
文件是保存在外存储器上(一般代指磁盘,也可以是优盘,移动硬盘)的数据集合。
文件操作体现在哪几个方面
数据的读取和写入可被视为针对文件输入和输出的操作,此时数据就像水流一样从外存储器流向内存,或者从内存流向外存储器,所以系统形象的文件操作为文件流。
C语言程序对文件的操作采用“文件缓冲机制”。就是说在程序中对文件的数据读写并不是直接操作文件中的数据,而是系统会为文件在内存中创建“文件缓冲区”。程序对文件的操作,其实是在缓冲区进行的。
根据数据的存储方式划分:
文件标识
文件操作步骤:
打开文件,让系统为文件创建文件缓冲区
函数名:fopen
头文件:#include
函数原型:函数名,函数参数列表(形参),函数返回值类型
FILE* fopen(const char *path,const char *mode);
函数的功能:打开文件,并为文件创建缓冲区
函数参数:
返回值:
文件的关闭,文件使用完毕,一定要记得释放
文件打开与关闭案例
//文件的打开与关闭
#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;
}
方式一
//单字符的读取
#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;
}
案例
//多字符读取
#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;
}
案例:
//多字符写入
#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指向的文件时判断是否遇到文件结束
函数参数:
返回值:
练习:实现一个文本文件的拷贝
/**
* 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);
}
案例:
/**
* 数据库读写案例:从键盘输入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();
}
}
案例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);
}