①定义一个文件指针
②将fopen函数的返回值赋值给文件指针
③判断文件指针是否为空
④如果为空,使用perror输出错误信息
⑤使用fclose函数关闭文件
⑥将文件指针置为空,方便下次使用
#include <stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "r");//以只读的形式打开文件test.txt
if (pf == NULL)//如果文件指针pf为空则输出错误信息
{
perror("fopen:");
}
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空,方便后续使用
return 0;
}
fopen("需要打开的文件主干和文件后缀(文件名和文件类型)","打开文件是为了做什么?");
“test.txt” - 要打开的文件
"r" - 以什么形式打开,r为只读
注意:①打开文件时,要保证文件存在,如果不存在会报错。②两个都需要加上双引号!!!
fp - 要关闭的文件
表1-1 使用文件的方式
注意:如果是以“w”形式打开的文件写入数据的话,每次写入时在打开文件的时候会将之前的数据清空。如果是要往文件内追加内容,在打开文件时需要以"a"的形式打开,这样就可以在文件的尾部继续写入数据。
需要读取时,在打开文件要以读取形式打开,即FILE* pf = fopen("test.txt", "r");
pf - 要读取的文件
一次读取:fgetc(pf);
循环读取:
char cont = 0;
while ( (cont = fgetc(pf) ) != EOF)
{
printf("%c ", cont);
}
#include <stdio.h>
int main()
{ //read 读取 write写入
FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//读取一次文件中的字符数据
int a = fgetc(pf);
printf("%c", a);
//循环读取文件中的字符数据
char cont = 0;//定义变量
while ( (cont = fgetc(pf) ) != EOF)//循环判断获取字符是否失败,失败的话会返回EOF,将获取到的内容赋值给变量cont
{
printf("%c ", cont);//如果正常获取,输出获取到的内容
}
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
需要写入时,在打开文件要以写入形式打开,即FILE* pf = fopen("test.txt", "w");
ch - 要写入的字符数据变量
pf - 要写入的文件
一次写入:
char ch = 'a';
fputc(ch, pf);
循环写入:
char ch = 0;
ch = getchar();
while (ch != '#')
{
fputc(ch, pf);
putchar(ch);
ch = getchar();
}
#include <stdio.h>
int main()
{ //read 读取 write写入
FILE* pf = fopen("test.txt", "w");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//写入一次字符数据
char c = 'a';
fputc(c, pf);//将字符a写入pf所指向的文件中
//循环写入字符数据,以#号结束
char ch = 0;
ch = getchar();//接收一个字符
while (ch != '#')//判断是否等于结束符#
{
fputc(ch, pf);//写入一次字符数据
putchar(ch);//输出到屏幕上
ch = getchar();//继续接收字符数据直到为#
}
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
需要读取时,在打开文件要以读取形式打开,即FILE* pf = fopen("test.txt", "r");
arr - 读取出来的数据存放的数组
8 - 需要读取的元素个数
pf - 需要读取的文件
注意:①读取个数为实际数据量n+1,因为其中包含了\0。例如文件数据为TianHua,如果是7的话只读取到TianHu+\0。②读取前要先保证文件内有数据可读。
#include <stdio.h>
int main()
{ //read 读取 write写入
FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//读取一行数据
char arr[10] = { 0 };
fgets(arr, 8, pf);
printf("%s",arr);
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
需要写入时,在打开文件要以写入形式打开,即FILE* pf = fopen("test.txt", "w");
“TianHua” - 要写入的字符串数据
pf - 要写入的文件
#include <stdio.h>
int main()
{ //read 读取 write写入
FILE* pf = fopen("test.txt", "w");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//写入一行数据
fputs("TianHua\n", pf);
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
需要读取时,在打开文件要以读取形式打开,即FILE* pf = fopen("test.txt", "r");
pf - 要读取的文件
pf之后参数与scanf格式一致
#include <stdio.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { "TianHua",20,90.9f };
//read 读取 write写入
FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//格式化读取数据
fscanf(pf, "%s %d %.2f", s.arr,(&s.age),(&s.score));
printf("%s %d %.2f\n", s.arr, s.age, s.score);
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
需要写入时,在打开文件要以写入形式打开,即FILE* pf = fopen("test.txt", "w");
pf - 要写入的文件
pf之后参数与printf格式一致
#include <stdio.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { "TianHua",20,90.9f };
//read 读取 write写入
FILE* pf = fopen("test.txt", "w");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//格式化写入数据
fprintf(pf,"%s %d %.2f",s.arr,s.age,s.score);
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
以二进制形式读取时,在打开文件时要以二进制读取形式打开,即FILE* pf = fopen("test.txt", "rb");
&s - 读取的数据存放的地址
sizeof(struct S) - 要读取的元素的大小
1 - 读取的次数
pf - 读取的文件
#include <stdio.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { 0 };
//rb 二进制形式读取 wb二进制形式写入
FILE* pf = fopen("test.txt", "rb");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//二进制形式读取数据
fread(&s, sizeof(struct S), 1, pf);
printf("%s %d %.2f", s.arr, s.age, s.score);
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
以二进制形式写入时,在打开文件时要以二进制写入形式打开,即FILE* pf = fopen("test.txt", "wb");
&s - 要写入的数据变量的地址
sizeof(struct S) - 要写入的元素的大小
1 - 写入的次数
pf - 写入的文件
#include <stdio.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { "TianHua",20,90.9f };
//rb 二进制形式读取 wb二进制形式写入
FILE* pf = fopen("test.txt", "wb");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//二进制形式写入数据
fwrite(&s, sizeof(struct S), 1, pf);
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
表2-1 顺序读写函数表
pf - 操作的文件流
0 - 偏移量
SEEK_SET - 文件开始位置
SEEK_CUR - 文件位置标记当前位置
SEEK_END - 文件末尾
#include <stdio.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { 0 };
FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//随机读取文件
char ch = fgetc(pf);
fseek(pf, 0, SEEK_SET);//文件开始
ch = fgetc(pf);
printf("%c\n", ch);
fseek(pf, 1, SEEK_CUR);//文件位置标记当前位置
ch = fgetc(pf);
printf("%c\n", ch);
fseek(pf, -3, SEEK_END);//文件末尾
ch = fgetc(pf);
printf("%c\n", ch);
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
运行结果
起始点 | 代码名字 | 用数字代表 |
文件开始 | SEEK_SET | 0 |
文件位置标记当前位置 | SEEK_CUR | 1 |
文件末尾 | SEEK_END | 2 |
表3-1 fseek函数中的“起始点”表示方法
pf - 操作的文件流
#include <stdio.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { 0 };
FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//随机读取文件
char ch = fgetc(pf);
fseek(pf, 0, SEEK_SET);//文件开始位置
ch = fgetc(pf);
printf("%c\n", ch);
printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
rewind(pf);//将文件指针位置归位到起始位置
printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
fseek(pf, 1, SEEK_CUR);//文件位置标记当前位置
ch = fgetc(pf);
printf("%c\n", ch);
printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
rewind(pf);//将文件指针位置归位到起始位置
printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
运行结果
pf - 要操作的文件流
#include <stdio.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { 0 };
FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
{
perror("fopen:");//输出错误信息
return;
}
//随机读取文件
char ch = fgetc(pf);
fseek(pf, 0, SEEK_SET);//文件开始位置
ch = fgetc(pf);
printf("%c\n", ch);
printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
rewind(pf);//将文件指针位置归位到起始位置
printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
fseek(pf, 1, SEEK_CUR);//文件位置标记当前位置
ch = fgetc(pf);
printf("%c\n", ch);
printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
rewind(pf);//将文件指针位置归位到起始位置
printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
fclose(pf);//关闭文件
pf = NULL;//将文件指针置空
return 0;
}
运行结果
直接运行程序是在内存上,数据不存储,用完就丢。使用文件把数据放到硬盘/磁盘就可以持久化。
磁盘上的文件是文件,在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。
包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
数据文件有两类:ASCII文件(文本文件)和二进制文件。
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。和键盘缓冲区是一个道理的。
?