该文章上一篇:C/C++文件操作(细节满满,part1)_仍有未知等待探索的博客-CSDN博客
个人主页:仍有未知等待探索_C语言疑难,数据结构,小项目-CSDN博客
目录
一、引言
通过上篇文章,已经了解了什么是文件、打开和关闭文件的操作,流的概念等。
如果对于上述的内容感到有点陌生了,不妨去看一看,文章链接在开头。
这篇文章的内容将会包含写文件的基本操作。
文件的顺序读写:是每次从第一个字符开始读和写。
文件的随机读写:是每次可以从任意一个位置读和写。
二、文件的顺序
适用文件 | 功能 | 函数名 | 适用于 |
文本文件 | 字符输入函数 | fgetc | 所有输入流 |
文本文件 | 字符输出函数 | fputc | 所有输出流 |
文本文件 | 文本行输入函数 | fgets | 所有输入流 |
文本文件 | 文本行输出函数 | fputs | 所有输出流 |
文本文件 | 格式化输入函数 | fscanf | 所有输入流 |
文本文件 | 格式化输出函数 | fprintf | 所有输出流 |
二进制文件 | 二进制输入 | fread | 文件 |
二进制文件 | 二进制输出 | fwrite | 文件 |
1、输入流和输出流
流相当于是一个过渡的过程。怎么判上述函数是输入流还是输出流呢?
我们可以站在内存的视角来看,如果是数据流向内存,我们就可以看作是输入流。反之,则是输出流。
就以fgetc和fputc为例:
2、fputc
1.功能
将一个字符character写进stream流中。
2. 参数
character:字符(字符的本质就是ASCII码值,是整数)。
stream:文件指针。
3.用法
#include<stdio.h>
int main()
{
//以‘只写’的方式打开文件
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
//输入
for (int i = 'a'; i <= 'z'; i++)
fputc(i, pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
4.注意
用什么方式打开文件就只能完成该功能。就比如说,以‘只写’的方式打开文件,就不能进行读取操作。
如果对于打开方式模糊了,请点击下面链接,查看上一篇的内容:
3、fgetc
1.功能
从stream流中获取数据。
2.参数
文件指针类型的stream流。
3.用法
如果获取失败,函数将返回EOF
//以‘只读’的方式打开文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
//输出
int ch;
while((ch=fgetc(pf))!=EOF)
{
printf("%c ",ch);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
4、fputs
1、功能
将一个字符串写入流中。
2、参数
str:需要写入文件的参数。
stream:文件流。
3、用法
如果没有‘\n’的话,他会把数据输入在一行。
如果把文件指针pf换成stdout的话,程序会把数据打印在屏幕上。
#include<stdio.h>
int main()
{
//以‘只写’的方式打开文件
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
fputs("abcd", pf);//不换行写法
fputs("abcd\n", pf);//换行写法
fputs("abcd", stdout);//将数据打印在屏幕上
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
5、fgets
1、功能
从流中获取字符串。
2、参数
str:字符串。
num:读取的个数。
stream:文件流。
3、用法
如果获取失败,函数将返回EOF
#include<stdio.h>
int main()
{
//以‘只读’的方式打开文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
char str[20];
fgets(str, 10, pf);
printf("%s", str);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
4、注意
- 函数最多只会读取一行的数据。
- 当数据足够多时,参数为num,函数只会读取num-1个数据。
6、fprintf
1、功能
将格式化数据写入文件流中。
2、参数
通过将fprintf和printf的参数相比较,会发现,fprintf的参数就比printf的参数多了一个文件指针。
3、用法
#include<stdio.h>
struct S
{
float f;
char ch;
int n;
};
int main()
{
struct S s = { 4.14f,'w',1 };
//以‘只 写’的方式打开文件
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
printf("%f %c %d\n", s.f, s.ch, s.n);
fprintf(pf,"%f %c %d\n", s.f, s.ch, s.n);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
7、fscanf
1、功能
从流中读取数据。
2、参数
fscanf和scanf的参数差不多,多了一个文件流stream。
3、 用法
#include<stdio.h>
struct S
{
float f;
char ch;
int n;
};
int main()
{
struct S s = { 4.14f,'r',1 };
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
fscanf(pf, "%f %c %d", &(s.f), &(s.ch), &(s.n));
printf("%f %c %d", s.f, s.ch, s.n);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
8、fwrite
1、功能
将ptr中的数据写入流中,大小为size,个数为count。
2、参数
ptr:指向要写入文件流中的数据的指针。
size:每个数据的大小。
count:数据个数。
stream:要写入的文件流中。
3、用法
#include<stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "wb");//abcdef
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
char str[] = "abcd";
fwrite(str, sizeof(char), sizeof(str) / sizeof(str[0]), pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
4、注意
文件的打开方式要和函数匹配,要用二进制的写的方式。
9、fread
1、功能
从文件流中读取数据。
2、参数
ptr:指向文件流中的数据所要存到的位置的指针。
size:每个数据的大小。
count:数据个数。
stream:文件流。
3、用法
#include<stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "rb");//abcdef
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
char str[20];
fread(str, sizeof(char), sizeof(str) / sizeof(str[0]), pf);
printf("%s", str);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
4、注意
文件的打开方式要和函数匹配,要用二进制的读的方式。
三、文件的随机读写
根据文件指针的位置和偏移量来确定文件指针的位置。
SEEK_SET | Beginning of file |
SEEK_END | Current position of the file pointer |
SEEK_CUR | End of file |
1、fseek
功能是改变文件指针的位置。
#include<stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "r");//abcdef
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
int ch;
ch = fgetc(pf);//a
printf("%c\n", ch);
ch = fgetc(pf);//b
printf("%c\n", ch);
ch = fgetc(pf);//c
printf("%c\n", ch);
fseek(pf, -1, SEEK_CUR);
ch = fgetc(pf);
printf("%c\n", ch);//c
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
2、ftell
功能是返回文件当前指针的偏移量。
#include<stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "r");//abcdef
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
int ch;
ch = fgetc(pf);//a
printf("%c\n", ch);
ch = fgetc(pf);//b
printf("%c\n", ch);
ch = fgetc(pf);//c
printf("%c\n", ch);
int pos = ftell(pf);
printf("%d", pos);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
3、rewind
功能是将文件指针返回起始位置。
#include<stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "r");//abcdef
if (pf == NULL)
{
perror("fopen");
return 0;
}
//处理
int ch;
ch = fgetc(pf);//a
ch = fgetc(pf);//b
ch = fgetc(pf);//c
int pos = ftell(pf);
printf("%d\n", pos);
rewind(pf);
pos = ftell(pf);
printf("%d", pos);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
四、二进制文件和文本文件
根据数据的存储形式,文件可以分为二进制文件和文本文件。
数据在文件中以二进制存储,就是二进制文件。
数据在文件中以ASCII码值存储,就是文本文件。
五、文件读取结束的标志
在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。
1、文本文件读取结束标志
fgetc——判断是否为EOF
fgets——判断是否为NULL
2、二进制文件读取结束标志
fread——判断返回值是否小于实际要读的个数。
六、文件缓冲区
谢谢大家支持!