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