引言
介绍和文件操作中文件的顺序读写相关的函数
看这篇博文前,希望您先仔细看一下这篇博文,理解一下文件指针和流的概念:C语言【文件操作】详解上-CSDN博客文章浏览阅读606次,点赞26次,收藏4次。先整体认识一下文件是什么,会打开和关闭文件。 关于对文件操作函数在下部分来介绍https://blog.csdn.net/2401_88433210/article/details/146432061?spm=1011.2415.3001.10575&sharefrom=mp_manage_link
一、文件的顺序读写函数介绍
顺序读写函数(都需要头文件stdlib.h):
函数名 功能(以文件为对象来说) 适用于 fgetc 字符输入函数 所有输入流(文件流和stdin) fputc 字符输出函数 所有输出流(文件流和stdout) fgets 文本行输入函数 所有输入流(文件流和stdin) fputs 文本行输出函数 所有输出流(文件流和stdout) fscanf 格式化输入函数 所有输入流(文件流和stdin) fprintf 格式化输出函数 所有输出流(文件流和stdout) fread 二进制输入函数 文本输入流 fwrite 二进制输出函数 文本输出流 上面说的适用于所有输入流⼀般指适用于标准输入流和其他输入流(如文件输入流)
所有输出流⼀般指适用于标准输出流和其他输出流(如文件输出流)。
下面看代码理解
共四对函数,下面一个一个介绍
1.fputc和fgetc
fputc
fputc函数原型:fputc - C++ Reference (cplusplus.com)
int fputc ( int character, FILE * stream );
写字符到文件中
成功写入到文件中,返回对应的ASCII值
如果写入失败,返回EOF
代码一(fputc):
以只写的形式'w'打开文件data.c,没有该文件的话会自动创建一个该文件,并用fputc函数写入字符a到z。
//写字符到文件中
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* pf = fopen("data.txt", "w");//打开文件
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写字符
//fputc('a', pf);
//fputc('b', pf);
//fputc('c', pf);
//fputc('d', pf);
//fputc('e', pf);
for (int i = 'a'; i <= 'z'; i++)
{
fputc(i, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果:成功写入
fgetc
fgetc函数原型:fgetc - C++ Reference (cplusplus.com)
int fgetc ( FILE * stream );
(从文件中)读取字符成功,返回字符对应的ASCII值
如果读取失败或者遇到文件末尾,返回EOF
如果读取失败,会设置一个错误状态值------用ferror来判断(下一节讲)
如果遇到文件末尾,会设置一个遇到文件末尾的状态值------用feof来判断(下一节讲)
代码二(fgetc):
以只读的形式'r'打开文件data.c,用fgetc函数读取字符a到z。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* pf = fopen("data.txt", "r");//打开文件
if (pf == NULL)
{
perror("fopen");
return 1;
}
int ch = fgetc(pf);
printf("%c\n", ch);//a
ch = fgetc(pf);
printf("%c\n", ch);//b
ch = fgetc(pf);
printf("%c\n", ch);//c
//会一个一个读出来
ch = 0;
while ((ch = fgetc(pf)) != EOF)
{
printf("%c ", ch);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
2.fputs和fgets函数
fputs函数原型:fputs - C++ Reference (cplusplus.com)
int fputs ( const char * str, FILE * stream );
将字符串,写入到文件中(\0不会写入到文件中)
成功后,将返回非负值。
出错时,该函数返回 EOF 并设置错误指示符 (ferror)。
fputs
代码一(fputs):
以只写的形式'w'打开文件data.c,没有该文件的话会自动创建一个该文件,并用fputs函数写入字符串“hello word”。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* pf = fopen("data.txt", "w");//打开文件
if (pf == NULL)
{
perror("fopen");
return 1;
}
fputs("hello word\n", pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
fgets
fgets函数原型:fgets - C++ Reference (cplusplus.com)
char * fgets ( char * str, int num, FILE * stream );
(从文件中)读取(num - 1)个字符到str中。(会读取换行符\n,最后一个位置是\0)
读取成功返回字符串str的地址
如果在读取任何字符之前发生这种情况,则返回的指针为空指针(并且 str 的内容保持不变)。
如果在尝试读取字符时遇到文件结尾,则设置 eof 指示符 (feof)。
如果发生读取错误,则设置错误指示符 (ferror) 并返回 null 指针(但 str 指向的内容可能已更改)。
代码二(fgets):
以只读的形式'r'打开文件data.c,用fgets函数读取字符串到数组中。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* pf = fopen("data.txt", "r");//打开文件
if (pf == NULL)
{
perror("fopen");
return 1;
}
char arr[20] = { 0 };
fgets(arr, 20, pf);
printf("%s", arr);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
调试看arr数组里面的内容:
3. fscanf和fprintf函数
fprintf
fprintf函数原型:fprintf - C++ Reference (cplusplus.com)
int fprintf ( FILE * stream, const char * format, ... );
可以类比printf函数来使用,只不过多了一个写入的流对象的指针
成功后,将返回写入的字符总数。
如果发生写入错误,则设置错误指示符 (ferror) 并返回负数。
如果在写入宽字符时出现多字节字符编码错误,则 errno 设置为 EILSEQ 并返回负数。
代码一(fprintf):
以只写的形式'w'打开文件data.c,没有该文件的话会自动创建一个该文件,并用fprintf函数写入数据,任何类型的数据都可以
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* pf = fopen("data.txt", "w");//打开文件
if (pf == NULL)
{
perror("fopen");
return 1;
}
char arr[20] = "hello";
int num = 100;
double PI = 3.14;
fprintf(pf, "%s %d %f", arr, num, PI);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
fscanf
fscanf函数原型:fscanf - C++ 参考 (cplusplus.com)
int fscanf ( FILE * stream, const char * format, ... );
类比scanf来使用,只不过多了一个流对象的指针
成功后,该函数返回成功填充的参数列表的项目数。
如果在读取时发生读取错误或到达文件末尾,则会设置正确的指示符(feof 或 ferror)。而且,如果在成功读取任何数据之前发生任何情况,则返回 EOF。
代码二(fscanf):
以只读的形式'r'打开文件data.c,用fscanf函数读取内容到结构体中。
struct S
{
char arr[20];
int num;
double PI;
};
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* pf = fopen("data.txt", "r");//打开文件
if (pf == NULL)
{
perror("fopen");
return 1;
}
struct S s = { 0 };
//读文件
fscanf(pf, "%s %d %lf", s.arr, &(s.num), &(s.PI));
printf("%s %d %lf\n", s.arr, s.num, s.PI);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
4.fwrite和fread
fwrite
fwrite函数原型:fread - C++ Reference (cplusplus.com)
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
ptr :指向要写入的元素数组的指针,转换为 const void*。
size :要写入的每个元素的大小(以字节为单位)。
count : 元素数,每个元素的大小为 size 字节。stream:指向指定输出流的 FILE 对象的指针。
结合代码来看一下就明白了:
代码一(fwrite):
以只写的形式'w'打开文件data.c,没有该文件的话会自动创建一个该文件,并用fwrite函数,写入二进制数据。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* pf = fopen("data.txt", "w");//打开文件
if (pf == NULL)
{
perror(pf);
return 1;
}
int arr[20] = { 1,2,3,4,5 };
fwrite(arr, sizeof(arr[0]), 5, pf);
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
以二进制的形式来看:
第一步:
第二步:
第三步: (看)
fread
fread函数原型:fread - C++ Reference (cplusplus.com)
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
ptr :指向要写入的元素数组的指针,转换为 const void*。
size :要写入的每个元素的大小(以字节为单位)。
count : 元素数,每个元素的大小为 size 字节。stream:指向指定输入流的 FILE 对象的指针。
结合代码来看一下就明白了:
代码二(fread):
以只读的形式'r'打开文件data.c,用fread函数读取数据。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* pf = fopen("data.txt", "r");//打开文件
if (pf == NULL)
{
perror(pf);
return 1;
}
int arr[20] = { 0 };
fread(arr, sizeof(arr[0]), 5, pf);
for (int i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
二、理解函数适用的流
对应适用于所以流的函数,其参数部分的流部分可以是文件指针FILE的指针,也可以是屏幕和键盘的输入输出流即stdin 和 stdout 流。
以fprintf函数来举个例子,其他类似:
#include<stdio.h>
#include<stdlib.h>
struct S
{
char arr[20];
int num;
double pai;
};
int main()
{
struct S s = { "world", 202, 3.14 };
fprintf(stdout, "%s %d %.2lf", s.arr, s.num, s.pai);
return 0;
}
运行结果: