1.思路梳理
文件操作中的函数要注意是对文件进行操作,而不是对输出屏幕进行操作
在对文件进行操作前,要先打开函数-fopen
对文件进行写入时有以下函数
fputc fputs fwrite fprintf
对文件进行读取时有以下函数
fgetc fgets fread fscanf
对文件操作完成后,要关闭文件-fclose
另外文件指针默认是指向文件开头,而要对文件部分进行操作时
涉及到
ftell(返回指针位置)函数、fseek(移动指针)函数、
feof(判断文件执行情况)函数
frewind(将指针移回文件开头)函数
fmove(删除文件)函数
进行一次文件操作的格式代码:
FILE* fp; //定义一个文件指针
fp=fopen("文件位置","文件打开方式"); //用文件指针打开文件
if (fp == NULL) //判断文件是否存在
{
printf("文件打开失败");
return; //return 会直接结束函数
}
//...文件具体操作(读取 or 写入)
fclose(fp); //文件操作完成,关闭文件
2.文件操作的作用
文件操作:将程序的数据(内存中)存在盘符里的过程、及将盘符的内存读取到内存的过程
文件操作主要包括:读档和存档
3.文件指针和文件操作函数
FILE* fp;//先定义文件指针
1.打开和关闭文件 fopen fclose
fopen格式:fopen(“文件路径”,“文件打开方式”);
fclose格式:fclose(文件指针名);
(每次文件打开之后需要关闭文件)
1.文件的路径,一般写相对路径
2.第二个参数是文件的打开方式 主有三种 rwa
r read 读取
从文件中读取数据 如果文件不存在 则打开失败
w write 写入
清空文件然后写入 如果文件不存在则创建一个新文件
a append 追加
在原文件后面增加新内容 文件不存在 则创建新文件
3.修饰内容 b t
b 表示二进制文件
t 表示文本文件
rb 用读取的方式打开一个二进制文件,如果文件不存在就会打开失败
rt 用读取的方式打开一个文本文件(t可以省略)
- 如果后面加一个+ 表示文件可读写
rb+ 用读取的方式打开一个二进制文件 文件可以读写
(类似的可以写成 ab+ wb+)
2.文件读写的函数
文本文件:
每次单独的读取一个字符的内容 fgetc fputc
fgetc fputc 每次从文件中读取、写入一个字符
格式:
ch = fgetc(fp);//读取文件中的一个字符
putchar(ch);//将读取到的字符输出到屏幕
char str[128];
fgets(str, 128, fp1);//读取一行,不超过128个字符,文件指针 fgets 需要与字符数组搭配使用
输出fgetc、fgets的内容需要putchar、puts函数
fputc函数的写入方式:
char str[128] = "hello world";
for (int i = 0; str[i] != '\0'; ++i)
{
fputc(str[i], fp);
}
fgets fputs 以字符串的方式进行读写
char str[128];
fgets(str, 128, fp1);//读取一行,不超过128个字符,文件指针 fgets 需要与字符数组搭配使用
puts(str);//puts 会在末尾自动加\n
//方式1.读取全部文件内容的
while (fgets(str, 128, fp1) != NULL)//注意是一行不超过128,而不是所有内部不超过128
{
puts(str);
}
//方式2.读取全部文件内容
while (1)
{
fgets(str, 128, fp1);
puts(str);
if (feof(fp))break;//feof表示文件末尾的值,是1表示已经读到文件末尾,是0表示文件还未读取完成
}
fclose(fp1);
char str1[128] = "刘你要加油";
fputs(str1, fp1);//将一串字符写入到文件当中
fscanf fprintf 格式化读取
fscanf-获取文件内内容
fscanf(fp3, "%d\t%s\n", &st.ID, st.name)
fprintf-将内容写到文件中
格式:fprintf(fp,"格式占位符",数据);
STU arr[4] = { 1,"张三",2,"李四",3,"王五",4,"赵六" };
for (int i = 0; i < 4; ++i)
{
fprintf(fp2, "%d\t%s\n", arr[i].ID, arr[i].name);
}
fread fwrite(二进制文件的读写方式)
fread函数的用法-读取内容
STU st;
while (fread(&st, sizeof(STU), 1, fp)!=0)
{
printf("%d\t%s\n", st.ID, st.name);
}
fwrite函数的用法-写入内容
//将一个结构体看成一个整体
fwrite(arr, sizeof(STU), 4, fp3);//第一个地址 第二个单个整体的大小 第三个“整体“的个数第四个文件指针
一般文件的读写不会同时进行
比如:游戏开始之前进行读档 游戏结束的时候存档写入文件
4.说明
二进制文件:用计算机方式存放的文件,比如mp3 wav
二进制文件文件的后缀可以是任何格式
(二进制文件用记事本打开的时候会乱码)
文本文件就是用文本文件打开不会乱码的文件
(似乎将所有的文件分成了二进制文件和文本文件)
f–> function 函数的意思
新版函数
fopen–>fopen_s
fopen_s(&fp,文件路径,文件打开方式)
fopen(文件路径,文件打开方式)
文件的读取过程中要注意文件内应具有一定的规律
scanf和fscanf两个函数在读取字符串的时候中间不能有空格
文本文件和二进制文件的区别
文本文件不会乱码,但是保密性不强
二进制文件会乱码但是保密性强
二进制文件计算机在读取的时候更快,适合编程使用
几个常见的函数
fseek 移动文件指针
fseek(fp,sizeof(STU),SEEK_SET)
将文件指针fp,从文件的开头移动sizeof(STU)个字节
正数表示往后移动,负数表示往前移动、SEE_SET-文件开头、SEEK_END-文件末尾、SEEK_CUR文件指针当前位置
ftell 计算文件内部指针的偏移,单位-字节 ftell(fp)
feof 判断文件执行情况
rewind 将文件指针移回开头
文件有文件的内部指针,指向当前读写的位置
r打开,内部指针在文件的开头
w\a打开,内部指针在文件的末尾
remove 删除文件 remove(“123.txt”);
5.代码实例
#include<stdio.h>
//预制结构体
typedef struct student //结构体类型
{
int ID;
char name[100];
///....
}STU;
//预制联合
union MyUnion
{
int x;
float y;
};
//预制枚举
enum dir
{
UP, DOWN, LEET, RIGH//常量 有名字可以提高代码可读性
};
//结构体-联合-枚举练习
void test()
{
student liu;
liu.ID;
STU beiwang;
beiwang.ID;//.运算符
STU *p = &beiwang;
p->ID;// ->箭头运算符
union MyUnion beibei;
beibei.x = 3;
beibei.y = 4.0f;//给一个成员赋值,其它成员的值就会失效
}
void readFile()
{
FILE* fp;
fp = fopen("123.txt","r");
if (fp == NULL)
{
printf("文件打开失败");
return;//return 会直接结束函数
}
char ch;
//ch = fgetc(fp);//读取文件中的一个字符
//putchar(ch);//将读取到的字符输出到屏幕
//读入,并输出多个字符
while (1)//
{
ch = fgetc(fp);
if (ch == EOF) break;//读到文件末尾表示结束读取 EOF=end of file
putchar(ch);
}
fclose(fp);
FILE* fp1;
fp1 = fopen("1234.txt", "r");
if (fp1 == NULL)
{
printf("文件打开失败");
return;//return 会直接结束函数
}
char str[128];
fgets(str, 128, fp1);//读取一行,不超过128个字符,文件指针 fgets 需要与字符数组搭配使用
puts(str);//puts 会在末尾自动加\n
//方式1.读取全部文件内容的
while (fgets(str, 128, fp1) != NULL)//注意是一行不超过128,而不是所有内部不超过128
{
puts(str);
}
//方式2.读取全部文件内容
while (1)
{
fgets(str, 128, fp1);
puts(str);
if (feof(fp))break;//feof表示文件末尾的值,是1表示已经读到文件末尾,是0表示文件还未读取完成
}
fclose(fp1);
}
void writeFile()
{
FILE* fp;
fp = fopen("写入.txt","w");
if (fp == NULL)
{
printf("文件打开失败");
return;//return 会直接结束函数
}
char str[128] = "hello world";
for (int i = 0; str[i] != '\0'; ++i)
{
fputc(str[i], fp);
}
fclose(fp);
FILE* fp1;
FILE* fp2;
fp1 = fopen("写入1.txt","w");
if (fp1 == NULL)
{
printf("文件打开失败");
return;//return 会直接结束函数
}
char str1[128] = "刘你要加油";
fputs(str1, fp1);//将一串字符写入到文件当中
fclose(fp1);
fp2 = fopen("写入3.txt", "w");
if (fp2 == NULL)
{
printf("文件打开失败");
return;//return 会直接结束函数
}
STU arr[4] = { 1,"张三",2,"李四",3,"王五",4,"赵六" };
for (int i = 0; i < 4; ++i)
{
fprintf(fp2, "%d\t%s\n", arr[i].ID, arr[i].name);
}
fclose(fp2);
}
void read()
{
FILE* fp;
fp = fopen("file.liu", "rb");//由于是二进制文件,所以文件的后缀可以是任何格式
if (fp == NULL)
{
printf("文件打开失败");
return;//return 会直接结束函数
}
STU st;
while (fread(&st, sizeof(STU), 1, fp)!=0)
{
printf("%d\t%s\n", st.ID, st.name);
}
fclose(fp);
}
void write()
{
FILE* fp3;
fp3 = fopen("file.liu", "wb");
if (fp3 == NULL)
{
printf("文件打开失败");
return;//return 会直接结束函数
}
STU arr[4] = { 1,"张三",2,"李四",3,"王五",4,"赵六" };
//将一个结构体看成一个整体
fwrite(arr, sizeof(STU), 4, fp3);//第一个地址 第二个单个整体的大小 第三个“整体“的个数第四个文件指针
fclose(fp3);
}
void show()
{
FILE* fp3;
fp3 = fopen("写入3.txt", "r");
if (fp3 == NULL)
{
printf("文件打开失败");
return;
}
STU st;
while (EOF != fscanf(fp3, "%d\t%s\n", &st.ID, st.name))
{
printf("%d\t%s\n",st.ID,st.name);
}
fclose(fp3);
}
int main()
{
readFile();
writeFile();
show();
write();
read();
getchar();
return 0;
}