文章目录
- 1.概念
- 1.1定义:
- 1.2分类
- 1.2.1程序文件
- 1.2.2数据文件
- 1.概念
- 2.存储方式
- 1.3文件名
- 2.文件的使用
- 2.1文件指针
- 2.2开闭函数
- 2.3顺序读写
- 2.3.1何为读写
- 2.3.2读写函数
- 1.字符输出fputc(输出到文件 写到文件中)
- 2.字符输入fgetc(输入到程序 读到程序中)
- 3.文本行函数
- 4.格式化函数
- 4.1...scanf--printf
- 4.2...fscanf--fprintf
- 4.3...sscanf--sprintf
- 5.二进制函数
- 2.4.随机读写
- 2.4.1功能函数
- 2.4.2读取结束判定
- 1.feof函数的使用
- 2.判定是否读取结束
- 3.文件缓冲区
- 3.1介绍
- 3.2缓冲文件系统
- 3.3冲刷函数fflush
1.概念
1.1定义:
文件:电脑文件,计算机文件。存储在长期储存设备(磁盘、光盘、磁带)或临时存储设备(计算机内存)中的一段数据流,归属于计算机文件系统管理下。
存储于长期存储设备的文件:
1.长期存储
2.程序或系统运行产生的临时数据,于程序或系统退出后删除。
1.2分类
1.2.1程序文件
源程序文件(.c)
目标文件(.obj)
可执行程序(.exe)。
1.2.2数据文件
程序
程序运行时读写的数据
程序运行读取数据或输出内容的文件
根据数据组织形式,数据文件分为:文本文件和二进制文件
1.概念
文本文件:
存在外存之前进行转换,以 ASCII 码形式存储。
二进制文件:
在内存中以二进制的形式存储,不加转换输出到外存。
2.存储方式
① 字符以 ASCII 形式存储
② 数值型数据
ASCII 形式
二进制形式
1.3文件名
文件存在的标识,操作系统根据文件名对其进行控制和管理。不同操作系统对文件命名规则略有不同,文件名的格式和长度因系统而异。为方便区分计算机中不同文件,给每个文件设定指定名称。
组成:
文件路径 + 文件名主干 + 文件后缀
C:\code2023\ test4_29 .txt
2.文件的使用
2.1文件指针
指向文件信息区(文件在内存中开辟的一个FILE结构体变量)的指针变量
2.2开闭函数
#include<stdlib.h>
打开:
FILE *fopen( const char *filename, const char *mode );
关闭:
int fclose( FILE *stream );
示例:
#include <stdio.h>
int main(void)
{
FILE* pf = fopen("test.dat", "w");
FILE* pf = fopen("C:\\code2023\\test4_29.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fclose(pf);
pf = NULL;
return 0;
}
- 程序能够打开的文件有限,文件属于一种资源。如果不释放,文件会被占用。可能会导致一些操作被缓冲在内存中,缓冲在内存中的数据不能正常写入文件中导致数据丢失。
2.3顺序读写
2.3.1何为读写
程序位于内存
数据位于硬盘上的文件
文件拿出数据:输入/读取(r)
程序存到文件:输出/写入(w)
2.3.2读写函数
1.字符输出fputc(输出到文件 写到文件中)
int fputc( int c, FILE *stream );
无符号字符输出到流
#include <stdio.h>
int main(void)
{
写文件-->程序输出到文件
w:无此文件创立文件
覆盖文件原有内容
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fputc('a', stdout);
fclose(pf);
pf = NULL;
return 0;
}
2.字符输入fgetc(输入到程序 读到程序中)
int fgetc( FILE *stream );
从流中读取字符
成功返回ASCII值
失败返回EOF
#include <stdio.h>
int main(void)
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int ret = fgetc(pf);
printf("%c\n", ret);
ret = fgetc(pf);
printf("%c\n", ret);
ret = fgetc(pf);
printf("%c\n", ret);
int ret = fgetc(stdin);
fclose(pf);
pf = NULL;
return 0;
}
3.文本行函数
输出:
int fputs( const char *string, FILE *stream );
fputs("abcdef\n", pf);
输入:
char *fgets( char *string, int n, FILE *stream );
fgets(arr, 4, pf);
点击 fgets函数详解 对fgets函数有更深刻的认识
4.格式化函数
4.1…scanf–printf
输出:
int printf( const char *format [, argument]... );
printf("%d", a);
printf("Hello,World!\n");
输入:
int scanf( const char *format [,argument]... );
scanf("%d %d", &a, &b);
4.2…fscanf–fprintf
输出:
int fprintf( FILE *stream, const char *format [, argument ]...);
fprintf(pf, "%s %d %f", p1.name, p1.dpi, p1.sens);
输入:
int fscanf( FILE *stream, const char *format [, argument ]... );
fscanf(pf, "%s %d %f", p1.name, &(p1.dpi), &(p1.sens));
4.3…sscanf–sprintf
输出:
int sprintf( char *buffer, const char *format [, argument] ... );
输入:
int sscanf( const char *buffer, const char *format [, argument ] ... );
示例:
#include <stdio.h>
struct S
{
char arr[10];
int age;
float f;
};
int main()
{
struct S s = { "hello", 20, 3.14f };
struct S tmp = { 0 };
char buffer[100] = { 0 };
sprintf(buffer, "%s %d %f", s.arr, s.age, s.f);
printf("%s\n", buffer);
sscanf(buffer, "%s %d %f", tmp.arr, &(tmp.age), &(tmp.f));
printf("%s %d %f\n", tmp.arr, tmp.age, tmp.f);
return 0;
}
scanf 标准格式化输入 - stdin
fscanf 所有输出流格式化输出- stdin / 文件
sscanf 从字符串中读取格式化数据
printf 标准格式化输出 - stdout
fprintf 所有输出流格式化输出 - stdout /文件
sprintf 格式化数据转换成字符串
5.二进制函数
输出:
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
fwrite(&s, sizeof(struct S), 1, pf);
输入:
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
fread(&s, sizeof(struct S), 1, pf);
点击 阿猿的《通讯录》查看通讯录,可以对上述函数又更清晰的理解
2.4.随机读写
2.4.1功能函数
int fseek( FILE *stream, long offset, int origin );移动指针到指定位置
origin:
① SEEK_CUR 当前位置
② SEEK_END 末尾位置
③ SEEK_SET 起始位置
fseek(pf, 5, SEEK_CUR);
long ftell( FILE *stream );返回与起始位置的偏移量
int ret = ftell(pf);
void rewind( FILE *stream );文件指针复位
rewind(pf);
2.4.2读取结束判定
1.feof函数的使用
int feof( FILE *stream );
读取结束:
读取失败 返回0
遇到文件尾 返回非0
int ferror( FILE *stream );
流中读取错误 返回非0
流中读取成功 返回0
#include <stdio.h>
#include <stdlib.h>
int main()
{
int ch = 0;
FILE* pf = fopen("test.txt", "r");
if (!pf)
{
perror("fopen");
return EXIT_FAILURE; //执行程序失败
}
// fgetc - 读取失败或文件结束返回EOF
while ((ch = fgetc(pf)) != EOF)
putchar(ch);
printf("\n");
if (ferror(pf))
puts("I/O error when reading)"); //读取失败
else if (feof(pf))
puts("End of file reached successfully");//遇到文件尾
fclose(pf);
pf = NULL;
return 0;
}
2.判定是否读取结束
① fgetc
读取结束返回 EOF
成功返回字符 ASCII 码
② fgets
读取结束返回 NULL
成功返回字符串首地址
③ fread
读取结束返回 读取元素个数
3.文件缓冲区
3.1介绍
为缓和 CPU 与 I/O 设备之间速度不匹配,文件缓冲区用以暂时存放读写期间的文件数据而在内存区预留的一定空间。使用文件缓冲区可减少读取硬盘的次数。
3.2缓冲文件系统
系统自动地在内存为程序中每一个正在使用的文件开辟一块文件缓冲区。
- 从内存向磁盘输出数据,先送到内存中的缓冲区,缓冲区装满后一起输送到磁盘上。
- 从磁盘向计算机读入数据,从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),从缓冲区逐个地将数据送到程序数据区(程序变量等)。
- 缓冲区的大小根据C编译系统决定。
3.3冲刷函数fflush
int fflush( FILE *stream );
将缓冲区内数据写到stream 指定文件。
成功返回 0
错误返回 EOF
高版本vs无法使用
fclose关闭文件时也会刷新缓冲区
#include <stdio.h>
#include <windows.h>
int main()
{
FILE* pf = fopen("test7.txt", "w");
if (!pf)
{
perror(fopen);
return 1;
}
fputs("abcdef", pf); //数据输出到buffer
//此时文件中无内容
Sleep(10000); //睡眠10s
fflush(pf); //刷新缓冲区
Sleep(10000); //睡眠10s
//此时数据到达文件
fclose(pf);
pf = NULL;
return 0;
}