编程之路,从0开始:文件操作(1)
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!
今天我们来讲C语言的文件操作。通过这节课,我们来学习如何使用C语言提供的一系列文件操作。
目录
1、文件操作引入
2、流
3、文件指针
4、文件的打开与关闭
5、文件的顺序读写
(1)fgetc
(2)fputc
(3)fgets
(4)fputs
(5)fscanf
(6)fprintf
(7)fread
(8)fwrite
1、文件操作引入
首先,我们要知道我们平时写的程序都是储存在内存中的,当结束程序后,我们的数据就消失了。所以为了长久的保存数据,我们可以使用文件来进行保存。
我们平时写的程序文件都是以.c、.obj、.exe为结尾的,文件操作我们主要是将数据存入.txt文件或从.txt文件读取。
在C语言中创建文件时,我们需要文件标识,并且一个文件只能有一个文件标识。通常,文件标识被称为文件名。
2、流
不知道大家在之前有没有了解过流这个概念。
其实,流就是为了从各种设备上读取数据,或者输出数据到设备上,而抽象出的一种概念。在这里我们可以简单理解为流淌着各种字符的河。
C语言默认打开三种流:标准输入流,标准输出流,标准错误流。
我们常用的scanf标准输入流中读取数据,printf就是将信息输出到标准输出流中。
3、文件指针
C语言FILE*文件指针用来维护流中的各种操作(这里且不深入讨论),我们在进行文件操作时必须要用到FILE*指针。
现在我们创建一个文件指针变量pf:
int main()
{
FILE* pf;
return 0;
}
我们可以使文件指针变量pf指向某个文件的文件信息区,这样我们就可以通过文件指针变量pf简洁的找到和访问与他相关的文件。
4、文件的打开与关闭
文件在读取之前应该先打开文件,在使用结束之后关闭文件。
在编写程序的时候,打开文件的同时,都会返回一个FILE*指针变量指向该文件。
现在我们使用fopen打开文件,fclose关闭文件:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
FILE* pf=fopen("test.txt", "w");//打开文件
if (pf != NULL)
{
//......
//文件操作
fclose(pf);//关闭文件
}
return 0;
}
以上是一套完整的打开和关闭文件流程。
这是函数fopen的原型:
第一个参数我们以字符串形式将文件名传入,当然这里我们并没有这个文件,当打开文件后他会在这个项目所在的文件目录下创建这个文件。
第二个参数我们以字符串形式把打开方式传入,以下是所有的打开方式:
实际上,我们常用的只有几个。
我们再看文件关闭函数原型:
我们将文件指针传入。就可以关闭这个文件指针指向的文件啦!
5、文件的顺序读写
下面我们来介绍几个顺序读写函数。我们可以利用这几个函数进行文件操作。
(1)fgetc
这个函数适用于所有输入流,是一个字符输入函数。
示例:
注意,我们要用“r”只读的方式打开文件,如果用“w”的方式打开文件,他会更改我们的文件内容。
我们想读取字符,所以我们先把test.txt文件中放上内容并保存:
现在读取字符,他会从第一个字符位置读取。我们把他读取的字符传给c,并打印到控制台上:
现在我们对代码进行升级:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
FILE* pf=fopen("test.txt", "r");//打开文件
int i = 0;
if (pf != NULL)
{
for (i = 0;i < 5;i++)
{
char c = fgetc(pf);
printf("%c", c);
}
fclose(pf);//关闭文件
}
return 0;
}
打印结果:
当每次读取完成后,光标后往后移动一位。这时候我们在进行读取操作,就会读取到下一个字符。我们利用这个特性,用循环嵌套进行读取,达到读取字符串的功能。但是由于我们只有三个字符,所以打印出来后两个位置是错误信息。
另外有一点需要注意,fgetc在遇到空格时会选择跳过。
(2)fputc
这个函数时字符输出函数,它适用于所有标准输出流。
我们传入想写入的字符,在传入文件指针:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
FILE* pf=fopen("test.txt", "w");//打开文件
int i = 0;
if (pf != NULL)
{
fputc('s', pf);//写入s
fclose(pf);//关闭文件
}
return 0;
}
现在我们打开test.txt发现他已经写入了字符s。
但是需要注意,我们不能实现这串代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
FILE* pf=fopen("test.txt", "w");//打开文件
int i = 0;
if (pf != NULL)
{
fputc('s', pf);//写入s
char c = fgetc(pf);//读取s
printf("%c", c);
fclose(pf);//关闭文件
}
return 0;
}
因为"w" 模式是写入模式,会清空文件内容,在写入之后,读取操作不会得到任何内容。
换句话说,就是在“w”写入模式下,我们不能用fgetc读取。
那么有什么办法实现以上代码呢?别急,我们后面会讲。
(3)fgets
这是一个文本行输入函数,同样适用于所有输入流。
我们把要存放读取字符串的地址传入,再把读取的字符个数传入,再传入文件指针。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
FILE* pf=fopen("test.txt", "r");//打开文件
int i = 0;
if (pf != NULL)
{
char c[100] = {0};
fgets(c,10,pf);
//puts(c);两种打印方法
printf("%s", c);
fclose(pf);//关闭文件
}
return 0;
}
需要注意的是,这个函数同样要再只读模式使用。
输出结果:
(4)fputs
这是一个文本行输出函数,它同样适用于所有输出流。
我们要把字符串地址和文件指针传入
使用:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
FILE* pf=fopen("test.txt", "w");//打开文件
int i = 0;
if (pf != NULL)
{
char c[100] = { 0 };
strcpy(c, "passion");
fputs(c, pf);
fclose(pf);//关闭文件
}
return 0;
}
注意换成了“w”模式。运行结束后,我们发现test.txt中的内容变成了passion。
(5)fscanf
这是一个格式化输入函数,适用于所有输入流。
我们发现这个函数的原型有些神奇,他的参数里面居然有个省略号!也就是说,它支持传入的参数个数是无限制的!
这里我们参考scanf来理解(他们只差一个字母f):
#include<stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
return 0;
}
这是最最最基础的scanf使用方法。我们可以输入a的数据。
那如果我们同时输入两个变量的数据呢?
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a,&b);
return 0;
}
它也可以实现。但是在这时候其实scanf里的参数数量已经改变了!我们可以同时输入三个,四个,五个数据都是可以的,
现在我们来看fscanf,它使用的时候我们要先传入文件指针,其他的参数使用和scanf一样。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
FILE* pf=fopen("test.txt", "r");//打开文件
int i = 0;
if (pf != NULL)
{
char c[100] = { 0 };
fscanf(pf,"%s",c);
printf("%s",c);
fclose(pf);//关闭文件
}
return 0;
}
我们在test.txt中写上passion,然后运行程序,就发现他能被打印出来啦!
(6)fprintf
这是一个格式化输出函数,适用于所有输出流。
它的使用可以类比printf,这里就直接给大家用了不做过多介绍了
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
FILE* pf=fopen("test.txt", "w");//打开文件
int i = 0;
if (pf != NULL)
{
char c[100] = { 0 };
strcpy(c, "asdasd");
fprintf(pf,"%s",c);
fclose(pf);//关闭文件
}
return 0;
}
(7)fread
这是一个二进制输入函数,适用于文件输入流。
这个函数传入的参数就相对来说复杂了一些:
第一个我们传入存放字符串的地址,第二个我们传入每个数据的字节大小,第三个参数我们传入数据的数量;第四个我们传入文件指针。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
FILE* pf=fopen("test.txt", "r");//打开文件
int i = 0;
if (pf != NULL)
{
char c[100] = { 0 };
fread(c,1,10,pf);
printf("%s", c);
fclose(pf);//关闭文件
}
return 0;
}
运行结果:
(8)fwrite
这是一个二进制输出函数,适用于文件输出流。
我们这里直接给大家上手用了:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
FILE* pf=fopen("test.txt", "w");//打开文件
int i = 0;
if (pf != NULL)
{
char c[100] = { 0 };
strcpy(c, "passion");
fwrite(c,1,10,pf);
printf("%s", c);
fclose(pf);//关闭文件
}
return 0;
}
运行结果:
好了,今天的内容就分享到这,下一节我们继续学习有关文件操作的知识。觉得有帮助的老铁点点关注支持一下,我们下期再见!