文件操作
一、什么是文件
1.程序文件就是在电脑上看到的(.txt),(.c),(.exe)这些都是文件,但是文件是有不同的类型,也就是说不是所有的文件都能直接打开,有些文件要用特殊的软件才能打开,比如说(.sln)解决方案文件,这个没有vs是不能打开的,就算用(.txt)文件方式打开也看不懂
/*
结构体.vcxproj"==>项目文件
结构体.vcxproj.filters"==>资源文件
结构体.sln"==》解决方案文件
2.数据文件:就是程序在执行的时候要在这个文件中读取数据,今天学的文件操作,就是读取的数据文件。
存储数据
二、文件的概念
1.文件名:每一个在同一个目录下只有唯一的文件标识(这是要加后缀名的),就是文件名。
因为有些不加文件后缀名的名字是一样的,但不会是相同的文件
三、文件路径
1.相对路径:就是从当前项目开始到当前文件的路径
2.绝对路径:就是从根目录开始到当前文件的路径
四、文件的常用函数
#include<stdio.h>
#include<stdlib.h>
typedef struct student
{
int id;
char name[20];
}STU;
void filewrite()//写入文件
{
/*
STU stu[3] = { {1,"张飞"},{2,"李飞"},{3,"不菲"} };
//对一个文件进行操作
//第一步打开文件
//fopen("路径","打开方式")打开文件
FILE*file = fopen("1.txt", "w");
//"r" 只读 如果用这个方式打开文件写入数据是要出错的,文件不存在也会出错 read
//"w" 只写,如果用这个方式打开文件读取数据是要出错的,文件不存在,会创建一个新的文件,文件存在那么会清空里面的内容,重新写入 write
//"a" 如果用这个方式打开文件,文件不存在会创建文件,从末尾写入数据 add
if (file == NULL)
{
printf("文件不存在
");
getchar();
//return -1;
exit(1);//异常退出
}
//第三步文件操作
//fputc('x', file);
for (int i = 0; i < 3; i++)
{
fprintf(file, "id: %d name: %s
", stu[i].id, stu[i].name);
}
fclose(file);
*/
FILE* file = fopen("3.txt", "wb");
char str[] = "asfaefeee";
int len = strlen(str);
fwrite(&len, sizeof(int), 1, file);
//将str的长度所占字节写入len中
fwrite(str, len, 1, file);
fclose(file);
}
void fileread()//读出文件
{
/*
FILE* file = fopen("1.txt", "r");
if (file == NULL)
{
printf("文件不存在
");
getchar();
exit(1);
}
STU stu[3] = { 0 };
for (int i = 0; i < 3; i++)
{
fscanf(file, "id: %d name: %s
", &stu[i].id, stu[i].name);
}
for (int i = 0; i < 3; i++)
{
printf("id: %d name: %s
", stu[i].id, stu[i].name);
}
//char ch = 0;//定义一个字符变量初始化为0
//ch = fgetc(file);//用这个变量来接收文件
//printf("%c
", ch);
char a1, a2, a3;
a1 = fgetc(file);
a2 = fgetc(file);
a3 = fgetc(file);
printf("%c%c%c", a1, a2, a3);
1.txt里有abc,文件指针是先指向文件开头,然后依次向后读取。
*/
FILE* file = fopen("3.txt", "rb");
char str[1024] = { 0 };
int len = 0;
fread(&len, sizeof(int), 1, file);
fread(str, len, 1, file);
printf("%s
", str);
fclose(file);
fclose(file);
}
//文件指针+文件操作的函数
//文件指针:FILE* 文件指针名
一、 第一步
-
定义文件指针: FILE*file
-
fopen("路径","打开方式")打开文件
-
文件的打开方式2
二、第二步
判断文件是否打开成功
if(file==NULL)//一般不要省略
{
printf("文件打开失败 ");
getchar;
return -1;
}
三、第三步
文件操作
四、关闭文件
fclose()==》打开文件要关闭
文件怎么写入的,就这么读出来
只读:是不能修改文件的
/*
"r"(只读) 为了输入数据,打开一个存在的文本文件 会出错
如果用这个方式打开文件写入数据是要出错的,文件不存在也会出错
"w"(只写) 为了输出数据,打开一个文本文件 新建文件
只写,如果用这个方式打开文件读取数据是要出错的,文件不存在,会创建一个新的文件,文件存在那么会清空里面的内容,重新写入
"a"(追加) 向文本文件末尾添加数据 出错
如果用这个方式打开文件,文件不存在会创建文件,从末尾写入数据
"rb"(只读) 为了输入数据,打开一个已存在的二进制文件 出错
b==>以二进制方式打开文件
‘+’==》可读可写,写是指的替换
"wb"(只写) 为了输出数据,打开一个二进制文件 新建文件
"ab"(追加) 向二进制文件末尾添加数据 出错
"r+"(读写) 为了书和写,打开一个文本文件 出错
"w+"(读写) 为了读和写,打开一个文本文件,新建文件
"a+"(读写) 为了读和写,打开一个文本文件 出错
"rb+"(读写) 为了读和写,打开一个二进制文件 出错
"wb+"(读写) 为了读和写,打开一个二进制文件 新建文件
"ab+"(读写) 为了读和写,打开一个二进制文件 出错
*/
4.fclose()关闭文件
fclose(file);
5.fgetc(文件指针) 读取一个字符
fgetc(file);
6.fputc(‘字符’;,文件指针) 写入一个字符
fputc('x', file);
7.fgets(字符指针,大小,文件指针) 读取一行字符,读n个
char str[100]={0};
fgets(str,10,file);
printf("%s ", str);
8.fputs(字符串,文件指针) 写入一串字符
fputs("adbjdq", file);
9.fprintf(文件指针,"格式化占位符...",变量...) 格式化写入文件
fprintf(file, "id: %d name: %s ", stu[i].id,stu[i].name);
10.fscanf(文件指针,"格式化占位符...",变量...)格式化读取以二进制方式读写数据
fscanf(file, "id: %d name: %s ", &stu[i].id, &stu[i].name);
11.fread(用来保存的字符数组,数据类型的大小,数据个数,文件指针)从文件中获取格式化的数据
12.fwrite(需要写进去的字符数组,数据类型的大小,数据的个数,文件指针)向文件中写入数据
FILE* file = fopen("4,txt", "wb");
int len = 10;
fwrite(&len, sizeof(int), 1, file);
//向文件中写入数据,&len就是写进去的东西
fclose(file);
FILE* file1 = fopen("4,txt", "rb");
int len1 = 0;
fread(&len1, sizeof(int), 1, file1);
//从文件中获取格式化的数据
//len1就是用来保存从4.txt中读取的数据
//因为写进去的时候是int类型的数据,所以用int类型来保存
printf("%d
", len1);
fclose(file1);
13.fseek(文件指针,偏移量,起始点) 移动文件指针
偏移量为正数往后移动,负数往前移动
起始点用0、1、2代替
0==》代表文件开始位置
1==》代表文件末尾位置
2==》代表文件末尾位置
文件末尾有一个标识 -1或者是EOF
FILE* file = fopen("1.txt", "r");
fseek(file, 6, 0);
fseek(file, -3, 1);
char ch = fgetc(file);
printf("%c
", ch);
fclose(file);
//fseek(文件指针,偏移量,起始点) 移动文件指针
14.ftell(文件指针)==》获取文件指针的偏移量//按字节数偏移的
15.feof(文件指针)==》判断文件指针是否读到末尾,读到末尾返回真,否者返回假
eof=end of file
注意:进行文件操作的时候,记得文件怎么写入的就怎么读出来,读写最好不要同时进行,注意你的打开方式。
int len = 0;
FILE* file = fopen("1.png", "rb");
fseek(file, 0, 2);//把文件指针移动到了末尾
len = ftell(file);//可以获取文件的所占的字节数
printf("%d
", len);
fclose(file);
//可以获取文件的大小
char str[1024] = { 0 };
FILE* file = fopen("1.txt", "r");
int len = 0;
while (!feof(file))
{
str[len++] = fgetc(file);
}
printf("%s
", str);
fclose(file);
//如果有读不出来,将文件换一种编码方式
//就是将文件另存为==》编码方式ANSI
在C语言的文件操作语法中,打开文件文件有以下12种模式,如下图:
打开模式 | 只可以读 | 只可以写 | 读写兼备 | |||
---|---|---|---|---|---|---|
文本模式 | r | w | a | r+ | w+ | a+ |
二进制模式 | rb | wb | ab | rb+ (r+b) | wb+ (w+b) | ab+ (a+b) |
其中,二进制模式与文本模式操作相似,只不过是以二进制流的形式读写而已,下面以文本模式为例分析:
1."r" 模式:
1.1 打开文件进行“只读”操作,即只能从文件读取内容。
1.2 若欲操作的文件不存在,则打开失败。
1.3 成功打开文件时,文件指针位于文件开头。
1.4 打开文件后,不会清空文件内原有内容。
1.5 可从文件中任意位置读取内容。
2."w" 模式:
2.1 打开文件进行“只写”操作,即只能向文件写入内容。
2.2 若欲操作的文件不存在,则新建文件。
2.3 成功打开文件时,文件指针位于文件开头。
2.4 打开文件后,会清空文件内原有的内容。
2.5 可向文件中任意位置写入内容,且进行写入操作时,会覆盖原有位置的内容。
3."a" 模式:
3.1 打开文件进行“追加”操作,即只能向文件写入内容。
3.2 若欲操作的文件不存在,则新建文件。
3.3 成功打开文件时,文件指针位于文件结尾。
3.4 打开文件后,不会清空文件内原有内容。
3.5 只能向文件末尾追加(写)内容。
4."r+"模式:
4.1 打开文件进行“读写”操作,即既可读取,又可写入。
4.2 若欲操作的文件不存在,则打开失败。
4.3 成功打开文件时,文件指针位于文件开头。
4.4 打开文件后,不会清空文件内原有内容。
4.5 无论是读取内容还是写入内容,都可在文件中任意位置进行,且进行写入操作时,会覆盖原有位置的内容。
5."w+"模式:
5.1 打开文件进行“读写”操作,即既可读取,又可写入。
5.2 若欲操作的文件不存在,则新建文件。
5.3 成功打开文件时,文件指针位于文件开头。
5.4 打开文件后,会清空文件内原有的内容。
5.5 无论是读取内容还是写入内容,都可在文件中任意位置进行,且进行写入操作时,会覆盖原有位置的内容。
6."a+"模式:
6.1 打开文件进行“读写”操作,即既可读取,又可写入。
6.2 若欲操作的文件不存在,则新建文件。
6.3 成功打开文件时,文件指针位于文件结尾。
6.4 打开文件后,不会清空文件内原有内容。
6.5 读取内容时,可以在任意位置进行,但写入内容时,只会追加在文件尾部。
附表格加强记忆:
打开模式 | 简述 | 若欲操作的文件不存在 | 成功打开文件后文件指针位置 | 是否清空原有内容 | 读取位置 | 写入位置 | 注 |
---|---|---|---|---|---|---|---|
r | 只读 | 打开失败 | 开头 | 否 | 任意位置读取 | 不可写入 | 无 |
w | 只写 | 新建 | 开头 | 是 | 不可读取 | 任意位置写入 | 写入时会覆盖原有位置内容 |
a | 只写 | 结尾 | 结尾 | 否 | 不可读取 | 只能尾部写入 | 无 |
r+ | 读写 | 打开失败 | 开头 | 否 | 任意位置读取 | 任意位置写入 | 写入时会覆盖原有位置内容 |
w+ | 读写 | 新建 | 开头 | 是 | 任意位置读取 | 任意位置写入 | 写入时会覆盖原有位置内容 |
a+ | 读写 | 新建 | 结尾 | 否 | 任意位置读取 | 只能尾部写入 | 无 |
不同的打开模式对应不同的操作方式,使用时需仔细规划。