一,程序与文件之间的输入与输出
了解这个知识很简单但也很重要,一张图即可搞定。
二,fopen与fclose
1,fopen函数
fopen的函数形式如下:
FILE* fopen(const char* Filename,const char* mode);
由图可知,fopen返回的是一个FILE*的指针类型,函数的第一个参数为文件名,第二个参数为文件的打开方式。
“r”表示以只读的方式打开,如果文件不存在,则会发生错误;
“w”表示以只写的方式打开,如果文件不存在,则会新建一个文件;
“a”表示向文件末尾添加数据;
“rb”表示以二进制的方式只读文件;
“wb”表示以二进制的方式只写文件;
当我们想要对某个文件进行读取内容的操作时,我们就需要先以读的方式打开文件,之后再使用专门的文件读取函数来进行操作。
例:
假如我们新建了一个“text.txt"的文本文档,我们想对它进行读的操作时。
我们就应该以上图的形式,创建一个FILE*的文件指针,再以这个文件指针接收fopen的返回值,以便后续使用pf进行读的操作。(当然,该函数的第二个参数是可以根据你的需要改变的)。
2,fclose函数
fclose函数形式如下:
int fclose(FILE* stream);
若fclose函数成功关闭一个文件,则会返回0;若关闭文件失败,则会返回EOF(-1)。
由此可见,fclose是用于关闭一个文件,所以fopen函数应当和fclose函数配套使用。如果你打开了一个文件,那么最后就需要使用fclose来关闭这个文件。
三,fgetc与fputc
1,fgetc函数
fgetc的函数形式如下:
int fgetc(FILE* stream);
fgetc函数是一个字符输入函数,作用是从文件中获得一个字符。既然是输入,那么我们就应该以读的形式打开这个文件,再使用fgetc函数来获取字符。
在先前,我们在工程中加入了一个”text.txt"文件,我们就以它为例吧。
这次我们使用fgetc函数,获取文件中的一个字符并打印。
int main()
{
FILE* pf = NULL;
pf = fopen("text.txt", "r");//以读的方式打开文件
char ch = fgetc(pf);//从文件中获取一个字符存入ch中
printf("%c", ch);//打印ch
fclose(pf);//关闭打开的文件
pf = NULL;//重新初始化pf,防止pf成为野指针
return 0;
}
结果:
屏幕中成功打印出字符a。
如果我们多次使用fgetc函数,那么我们就可以将文件中的内容一一打印出来。
int main()
{
FILE* pf = NULL;
pf = fopen("text.txt", "r");//以读的方式打开文件
char ch = 0;
ch = fgetc(pf);
printf("%c", ch);
ch = fgetc(pf);
printf("%c", ch);
ch = fgetc(pf);
printf("%c", ch);
ch = fgetc(pf);
printf("%c", ch);
fclose(pf);//关闭打开的文件
pf = NULL;//重新初始化pf,防止pf成为野指针
return 0;
}
结果:
由此可见,我们每使用一次fgetc函数后,光标就会向后移一个位置。
2,fputc函数
fputc的函数形式如下:
int fputc(int character,FILE* stream);
fputc函数是一个字符输出函数,作用是向文件中写入一个字符。既然是输出,我们就应以写的方式打开文件。当然,写的时候,原来的“text.txt"文件内容会被清空,在写入一个字符。
假如我们想要向文件中写入一个字符‘a',那么我们需要的代码如下:
int main()
{
FILE* pf = NULL;
pf = fopen("text.txt", "w");//以写!!的方式打开文件
fputc('a', pf);//写入一个字符a
fclose(pf);//关闭打开的文件
pf = NULL;//重新初始化pf,防止pf成为野指针
return 0;
}
代码走起来,那么我们原来的文件中abcd的内容就被清空,并且重新写入了一个a。
当然,如果我们在没有关闭文件的情况下再次使用fputc函数,那么光标也会跟着往后面移动,如下:
int main()
{
FILE* pf = NULL;
pf = fopen("text.txt", "w");//以写!!的方式打开文件
fputc('a', pf);//写入一个字符a
fputc('b', pf);
fputc('c', pf);
fputc('d', pf);
fclose(pf);//关闭打开的文件
pf = NULL;//重新初始化pf,防止pf成为野指针
return 0;
}
结果:
四,fgets与fputs
1,fgets函数
fgets的函数形式如下:
char* fgets(char* str,int num,FILE* stream);
fgets函数是一个文本行输出函数,它的作用是从文件中读取字符串放入一个字符串数组中。其中str为数组地址,num为想要读取的字符个数,第三个参数则为文件类型的指针。既然是从文件中读取数据,我们就需要以读的方式打开文件。
假如我们想要从text.txt文件中读取4个字符放在字符数组中,之后打印验证,那么代码如下:
int main()
{
FILE* pf = NULL;
pf = fopen("text.txt", "r");//以读!!的方式打开文件
char arr[5] = { 0 };//定义一个数组接受字符
fgets(arr, 5, pf);//从text.txt文件中读取字符
for (int i = 0; i < 5; i++)
{
printf("%c", *(arr + i));//打印字符
}
fclose(pf);//关闭打开的文件
pf = NULL;//重新初始化pf,防止pf成为野指针
return 0;
}
结果:
那么到了现在,可能就有细心的同学要问了,原本text.txt文件中只有abcd四个字符啊,为什么要把num参数写为5呢?
其实原因是这样,字符串的结尾是'\0',而在使用fgets函数的时候,为了保证读出来的数据是字符串,那么系统会将num最后一个参数以'\0'来代替,所以我们需要在原本的num个数上加1。
当我们不知道文件中的字符个数时,我们也可以使用以下对文件内容进行打印:
while (fgets(arr, 20/*来一个大点的数*/, pf) != NULL)
{
printf("%s", arr);
}
这样也可以打印出文件中的内容。
2,fputs函数
fputs的函数形式如下:
int fputs(const char* str,FILE* stream);
fputs函数是一个文本行输出函数,它的作用是将一个字符数组中的内容放入文件中。第一个参数为字符串数组的地址,第二个参数为FILE*的文件指针。既然是一个输出函数,我们就需要以写的方式打开一个文件。
假如我们要将一个字符串放入text.txt文件中,那我们就可以用到fputs函数:
int main()
{
FILE* pf = NULL;
pf = fopen("text.txt", "w");//以写!!的方式打开文件
fputs("hello world", pf);//将hello world字符串放入文件中
fclose(pf);//关闭打开的文件
pf = NULL;//重新初始化pf,防止pf成为野指针
return 0;
}
这样我们就可以将该字符串成功放入text.txt文件中。
结果:
当然,如果文本文件中原本就有内容,那么原来的内容会被删除,再被重新写入。
五,fscanf与fprintf
1,fscanf函数
fscanf的函数形式如下:
int fsacnf(FILE* stream,const char* format);
fscanf是一个格式化输入函数,它的作用是将文件中的内容格式化输入于程序。它的第一个参数是文件类型的指针,第二个参数是特定格式。多说无益,我们直接举例说明!
我们先定义一个结构体类型:
struct s//定义一个结构体
{
char name[20];
int age;
float score;
};
然后我们给text.txt文件初始化上如下内容:
然后我们使用fscanf函数将文件中的内容格式化输入结构体变量stu,然后打印于屏幕之上:
int main()
{
FILE* pf = NULL;
pf = fopen("text.txt", "r");//以写!!的方式打开文件
struct s stu = { 0 };//初始化结构体变量stu
fscanf(pf, "%s %d %f", stu.name, &(stu.age), &(stu.score));//从文件中读取数据输入于stu
printf("%s %d %f", stu.name, stu.age, stu.score);//打印stu的数据
fclose(pf);//关闭打开的文件
pf = NULL;//重新初始化pf,防止pf成为野指针
return 0;
}
代码走起来,结果如下:
注意:fscanf跟scanf类似,都需要进行取地址操作,而数组名就是地址,所以第一个stu.name我们没有进行取地址操作。
2,fprintf函数
fprintf的函数形式如下:
int fprintf(FILE* stream,const char* format);
fprintf是一个格式化输出函数,它的作用是将程序中的数据格式化输入于文件中。它的第一个参数是一个文件类型的指针,第二个参数是指定格式。
例:
我们定义了一个结构体,并且想要将一个结构体变量的内容输入于文件之中,那么代码如下:
struct s//定义一个结构体
{
char name[20];
int age;
float score;
};
int main()
{
FILE* pf = NULL;
pf = fopen("text.txt", "w");//以写!!的方式打开文件
struct s stu = { "zhangsan",18, 65.5f};//初始化结构体变量stu并赋值
fprintf(pf, "%s %d %f", stu.name, (stu.age), (stu.score));//将stu的数据格式化输入于文件之中
fclose(pf);//关闭打开的文件
pf = NULL;//重新初始化pf,防止pf成为野指针
return 0;
}
代码走起来,打开text.txt文件,我们就可以看到如下结果:
六,结语
文件操作函数还有许多许多,但我这里只讲了比较常见的文件操作函数,希望热爱学习的你们可以从中受益!