1、文件的打开和关闭
1.1文件指针
在缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”取名为FILE。
例如, VS2013编译环境提供的 stdio. h头文件中有以下的文件类型申明:
struct _ iobuf {
char *_ ptr;
int _ cnt;
char *_ base;
int _ flag;
int _ file;
int _ charbuf;
int _ bufsiz;
char *_ tmpfname;
};
typedef struct _ iobuf FILE;
不同的编译器的FILE类型包含的内容不完全相同,但是都大同小异。每打开一个文件系统都会自动的创建一个FILE类型的变量,并填充其中的信息,使用时不必关心细节。
一般都是通过文件指针来维护FILE这个结构的变量。
1.2文件的打开和关闭
在我们使用文件时要先打开文件,使用之后我们要关闭文件标准C规定要用fopen来打开文件,用fclose来关闭文件。
FILE*pf=fopen(const char*filename,const char*mode);
int fclose(FILE *stream);
fopen中第一个参数是文件的名字,第二个参数是打开的方式。
fclose中的参数是创建FILE指针的变量。
2、文件的打开方式和函数
2.1打开方式的介绍
文件使用方式 | 含义 | 如果文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开已经存在的文件文本 | 报错 |
“w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
“a”(追加) | 想文本的尾部添加数据 | 建立一个新的文件 |
“rb”(只写) | 为了输出数据,打开一个二进制文件 | 报错 |
"wb"(只读) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
2.2函数的对比
在对文件的管理和使用之中我们常常使用以下几种函数来对文件进行管理。
功能 | 函数名 | 适合用于 |
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
3.函数的讲解
PS:fgetc和fputc都是使用字符对文本进行管理,fgets和fputs都是利用字符串对文本进行管理
fscanf和fprintf是对结构体里面格式标准的数据进行管理,fread和fwrite是把文件利用二进制输入进去里面的数据是二进制出现的一般是一些二进制符号。
3.1 fputc和fgetc的讲解
代码解析:
利用fputc函数往data文件里面写入26个英文字母,英文字母的本质就是ascll码值
fputc的两个参数分别是要写入的数据和写入文件的指针。
int main()
{//新建文件
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
return -1;
}
char ch = 0;
for ( ch = 'a'; ch <= 'z'; ch++)
{
if (ch % 5 == 0)
{
fputc('\n',pf);
}
fputc(ch, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
代码解析:
fgetc的参数是你要读文件的文件指针这么一个参数,读到的数据(因为是字符)所以返回的是对应的ascll码的值,但是电脑能通过这个数字使用字符的方式打印出来。
int main()
{//新建文件
FILE* pf = fopen("data.txt", "r");
if (pf == NULL)
{
return -1;
}
int ch = fgetc(pf);
printf("%c ", ch);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
3.2 fputs和fgets的讲解
代码解析:
fputs函数是一个把arr里面的字符串放入到pf文件指针里面去的一个函数,先使用pf指针使用写的方式打开文件,然后使用fputs函数把数据写入到文件里面。
int main()
{//新建文件
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
return -1;
}
//
char arr[] = { "sdnjn" };
fputs(arr, pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
代码解析:
fgets函数是的参数有三个分别是要到入数据的数组,要导入的数据个数和到如数据的文件,导入完数据后就可以使用printf函数打印即可。
int main()
{//新建文件
FILE* pf = fopen("data.txt", "r");
if (pf == NULL)
{
return -1;
}
//
char arr[100] = { 0 };
fgets(arr, 6, pf);
printf("%s", arr);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
3.3 fprintf和fscanf的讲解
代码解析:
fprintf函数就是在printf函数的基础上加入了一个文件的指针,在使用上就是把结构体的数据放入了文件指针之中。
int main()
{
struct s sl = { 2,3.14f,'e' };
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
perror("pf err");
return -1;
}
fprintf(pf,"%d %f %c", sl.a, sl.b, sl.c);
fclose(pf);
pf = NULL;
return 0;
return 0;
}
代码解析:
fscanf函数和scanf函数的差别是前面的文件指针,fscanf函数就是把文件里面的数据读出来放入到结构体里面去。
int main()
{
struct s sl = { 2,3.14f,'e' };
FILE* pf = fopen("data.txt", "r");
if (pf == NULL)
{
perror("pf err");
return -1;
}
fprintf(pf,"%d %f %c", sl.a, sl.b, sl.c);
struct s sb = {0};
fscanf(pf,"%d %f %c", &(sb.a),&(sb.b),&(sb.c) );
printf("%d %f %c", sb.a, sb.b, sb.c);
fclose(pf);
pf = NULL;
return 0;
return 0;
}
3.4fwrite和fread函数的讲解
代码解析:
fwrite函数有四个参数分别是写入数据的数组,数据的单位字节,数据的个数和你要写入数据的文件指针,写入的数据会变成二进制的符号,我们是看不懂的,但是电脑可以读懂利用函数fread即可。如下:
int main()
{
FILE* pf = fopen("data.txt", "wb");
if (pf == NULL)
{
perror("pf err");
return -1;
}
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
fwrite(arr, 4, 10, pf);
fclose(pf);
pf = NULL;
return 0;
}
代码解析:
利用函数fread把文件里面的二进制的数据给读出来了,然后使用printf函数打印即可。
int main()
{
FILE* pf = fopen("data.txt", "rb");
if (pf == NULL)
{
perror("pf err");
return -1;
}
int arr[10] = { 0 };
fread(arr, 4, 10, pf);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
fclose(pf);
pf = NULL;
return 0;
}
3.5 sprintf和sscanf函数的讲解(补充)
代码解析:
sprintf函数是把结构体的数据全部都放入到数组里面。
int main()
{
struct s sl = {3,3.14f,'c'};
char arr[100] = { 0 };
sprintf(arr,"%d %f %c\n",sl.a,sl.b,sl.c);
printf("%s", arr);
return 0;
}
代码解析:
sscanf是一个把数组的数据读出来的一个函数,前面是你要存放数据的数组。
int main()
{
struct s sl = {3,3.14f,'c'};//定义结构体
char arr[100] = { 0 };//存放数据
sprintf(arr,"%d %f %c\n",sl.a,sl.b,sl.c);//把数据存放到arr数组里面
printf("%s", arr);//打印数组
struct s tmp = { 0 };//后面sscanf把数据存放到这个里面
sscanf(arr,"%d %f %c", &(tmp.a), &(tmp.b), &(tmp.c));//把数据存放到arr里面
printf("%d %f %c", tmp.a, tmp.b, tmp.c);//打印arr里面的数据
return 0;
}
4、文件的随机读写
4.1fseek函数的介绍
该函数有三个参数第一个是文件指针,第二个就是从当前读取的文件字符开始走,字符SEE_CUR就是指当前的这个字符的位置,另外的两个是SEEK_SET从文件字符最开始的位置开始和SEEK_END从字符最后开始。
下列代码的意思(fseek)是:
(因为fgetc往文件后面走了一格)从文件pf中的当前位置(第二格)开始走-1的距离也就是往回走一格。 后面利用ch打印出来的值还是与上面ch打印出来的值是一样的。
int main()
{
FILE*pf=fopen("data.txt", "r");
if (pf == NULL)
{
return -1;
}
int ch=fgetc(pf);
printf("%c \n", ch);
fseek(pf,-1 , SEEK_CUR);
ch = fgetc(pf);
printf("%c", ch);
fclose(pf);
pf = NULL;
return 0;
}
4.2ftell函数的讲解
返回文件指针相对于起始的偏移量
例子如下:
文件中存放的数据是a和b最后使用ftell函数返回的值就是2也就是与起始的位置偏移了两格
int main()
{
FILE*pf=fopen("data.txt", "r");
if (pf == NULL)
{
return -1;
}
int ch=fgetc(pf);
printf("%c \n", ch);//a
ch = fgetc(pf);
printf("%c\n", ch);//b
int pos = ftell(pf);
printf("%d", pos);
fclose(pf);
pf = NULL;
return 0;
}
4.3rewind函数讲解
rewind函数的作用就是让文件指针返回到起始的位置
例子如下:
使用fgetc函数往后面走了两格但是使用了rewind函数后文件指针的位置就从起始开始了。
int main()
{
FILE*pf=fopen("data.txt", "r");
if (pf == NULL)
{
return -1;
}
int ch=fgetc(pf);
printf("%c \n", ch);//a
ch = fgetc(pf);
printf("%c\n", ch);//b
rewind(pf);
ch = fgetc(pf);//a
printf("%c\n", ch);
fclose(pf);
pf = NULL;
return 0;
}
以上就是在我们学文件指针时使用到的函数,如果派上用场了请多多点赞加关注,如果代码存在错误还请大佬指出,谢谢大家。