- 二进制文件:可以存储各种类型的数据,如整数、浮点数等,每条数据的长度不一定相同,它们通常需要特定的程序或解码器来读取和写入。此外,操作系统对二进制文件中的换行符处理方式与文本文件不同,例如在Windows系统中,不会对二进制文件中的换行符进行转换。
- 文本文件:只能存储字符型数据,且每条数据通常是固定长度的。文本文件可以直接使用文本编辑器进行读写,因为它们以人类可读的形式存储信息。在Windows系统中,文本文件在写入时会将换行符转换为“\r”,而在读取时会将其转换回原来的换行符。
• stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。• stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出 流中。• stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯。
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
FILE* pf;/
基本上每个文件都有一个文件信息区,这个文件信息区是一个FILE类型的结构体,它把这个结构体的地址放到pf,就可以通过pf去找到这个文件信息区,然后通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件。
//打开⽂件
FILE * fopen ( const char * filename, const char * mode );
//关闭⽂件
int fclose ( FILE * stream );
"r"
:以只读方式打开文件(默认为文本模式)。"w"
:以写入方式打开文件,如果文件存在则清空内容,如果文件不存在则创建新文件(默认为文本模式)。"a"
:以追加方式打开文件,如果文件不存在则创建新文件(默认为文本模式)。"r+"
:以读写方式打开文件,如果文件不存在则失败(默认为文本模式)。"w+"
:以读写方式打开文件,如果文件存在则清空内容,如果文件不存在则创建新文件(默认为文本模式)。"a+"
:以读写方式打开文件,如果文件不存在则创建新文件(默认为文本模式)。- "rb"(只读二进制模式):以只读方式打开一个二进制文件,如果文件不存在则打开失败。这种模式下,只能从文件中读取数据,文件指针默认位于文件开头。
- "wb"(只写二进制模式):以写入方式打开一个二进制文件,如果文件存在则会清空内容,如果文件不存在则会创建新文件。这种模式下,只能向文件中写入数据。
- "ab"(追加二进制模式):以追加方式打开一个二进制文件,如果文件不存在则会创建新文件。这种模式下,可以向文件末尾追加数据,但不会自动清空原有内容。
- "rb+"(读写二进制模式):以读写方式打开一个二进制文件,如果文件不存在则打开失败。这种模式下,可以从文件中读取数据,也可以向文件中写入数据,文件指针可以自由移动。
- "wb+"(写读二进制模式):以读写方式打开或创建一个二进制文件,如果文件存在则会清空内容。这种模式下,可以读取已有数据,也可以在任意位置写入数据。
- "ab+"(追加读写二进制模式):以读写方式打开一个二进制文件,如果文件不存在则会创建新文件。这种模式下,可以在文件末尾追加数据,也可以读取文件中的数据。
在使用
fopen
函数时,需要根据实际需求选择合适的mode
参数,以确保文件能够按照预期的方式进行操作。同时,由于fopen
函数可能会因为各种原因(如文件不存在、权限不足等)而失败,因此在调用后应该检查返回值,确保文件成功打开。
int main()
{
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
函数名
|
功能
|
适⽤于
|
fgetc
|
字符输⼊函数
|
所有输⼊流
|
fputc
|
字符输出函数
|
所有输出流
|
fgets
|
⽂本⾏输⼊函数
|
所有输⼊流
|
fputs
|
⽂本⾏输出函数
|
所有输出流
|
fscanf
|
格式化输⼊函数
|
所有输⼊流
|
fprintf
|
格式化输出函数
|
所有输出流
|
fwrite
|
⼆进制输出
|
⽂件
|
fread
|
⼆进制输⼊
|
⽂件
|
- fgetc:这个函数用于从指定的文件流中读取一个字符。它的函数原型为
int fgetc(FILE *stream)
,其中stream
是指向要读取的文件的指针。如果成功读取一个字符,fgetc会返回该字符的ASCII码值;如果遇到文件末尾或读取失败,则返回EOF(通常是-1)。每次调用fgetc后,文件内部的读指针会自动向后移动一个字节的位置。- fputc:这个函数用于将一个字符写入到指定的文件流中。它的函数原型为
int fputc(int c, FILE *stream)
,其中c
是要写入的字符,而stream
是指向要写入的文件的指针。如果写入成功,fputc会返回写入的字符的ASCII码值;如果写入失败,则返回EOF(通常是-1)。
int main()
{
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件
for (char ch = 'a'; ch <= 'z'; ch++)
{
fputc(ch, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
int ret;
while((ret = fgetc(pf))!=EOF)
{
printf("%c", ret);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
- fgets:这个函数用于从指定的文件流中读取一行字符串。它的函数原型为
char *fgets(char *str, int n, FILE *stream)
,其中str
是指向存储读取结果的字符数组的指针,n
是指定的最大读取字符数(通常为n-1,因为需要为结尾的空字符'\0'预留位置),stream
是指向要读取的文件的指针。如果成功读取,fgets会将读取的字符串加上结尾的空字符'\0'存储到str
指向的数组中,并返回该数组的地址;如果遇到文件末尾或读取失败,则返回NULL。fgets在读取过程中,遇到换行符、文件结束或者达到最大读取字符数时会停止读取。- fputs:这个函数用于将一个字符串写入到指定的文件流中。它的函数原型为
int fputs(const char *str, FILE *stream)
,其中str
是要写入的字符串(以空字符'\0'结尾),stream
是指向要写入的文件的指针。fputs会将字符串写入到文件中,直到遇到空字符'0'结束。如果写入成功,fputs返回非负值;如果写入失败,返回EOF(通常是-1)。
int main()
{
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
fputs("hello\n", pf);
fputs("world", pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
char arr[20] = "xxxxxxxxxxxxxxxxxxx";
fgets(arr, 10, pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
fgets函数只会读一行,当读完一行的所有字符后,会在后面补上一个‘\0’。再次调用fgets函数时,它则会读取下一行的数据。
fprintf:
- 功能:将格式化的数据写入到指定的文件中。
- 语法:
int fprintf(FILE *fp, const char *format, ...);
- 参数:
fp
是一个指向FILE
类型文件的指针,format
是一个字符串,定义了后续参数的输出格式,后续参数是可变的,对应于format
字符串中的格式说明符。- 返回值:成功写入的字符数,如果发生错误则返回一个负值。
fscanf:
- 功能:从指定的文件中按照给定的格式读取数据。
- 语法:
int fscanf(FILE *fp, const char *format, ...);
- 参数:
fp
是一个指向FILE
类型文件的指针,format
是一个字符串,定义了读取数据的格式,后续参数是地址列表,用于存储从文件中读取的值。- 返回值:成功读取并赋值的数据项个数,如果到达文件末尾或发生错误则返回
EOF
。
struct S
{
char name[20];
int age;
float score;
};
int main()
{
struct S s = { "小明",18,80.0f };
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fprintf(pf, "%s %d %f", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}
struct S
{
char name[20];
int age;
float score;
};
int main()
{
struct S s = { 0 };
FILE* pf = fopen("data.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fscanf(pf, "%s %d %f", &s.name, &s.age, &s.score);
fclose(pf);
pf = NULL;
return 0;
}
fwrite:
- 功能:将一个数据块写入到指定的文件中。
- 语法:
size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream);
- 参数:
buffer
是一个指向要写入数据的指针,size
是每个数据项的大小(以字节为单位),count
是要写入的数据项的数量,stream
是指向FILE
类型文件的指针。- 返回值:成功写入的数据项个数,如果发生错误则返回一个小于
count
的值。fread:
- 功能:从指定的文件中读取一个数据块。
- 语法:
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
- 参数:
buffer
是一个指向存储读取数据的内存区域的指针,size
是每个数据项的大小(以字节为单位),count
是要读取的数据项的数量,stream
是指向FILE
类型文件的指针。- 返回值:成功读取并赋值的数据项个数,如果到达文件末尾或发生错误则返回一个小于
count
的值。
int main()
{
int arr[] = { 1,2,3,4,5 };
FILE* pf = fopen("data.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int sz = sizeof(arr) / sizeof(arr[0]);
fwrite(arr, sizeof(arr[0]), sz, pf);
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
int arr[5] = { 0 };
FILE* pf = fopen("data.txt", "rb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int sz = sizeof(arr) / sizeof(arr[0]);
fread(arr, sizeof(arr[0]), sz, pf);
fclose(pf);
pf = NULL;
return 0;
}
int fseek ( FILE * stream, long int offset, int origin );
其中:
- stream:是一个指向 FILE 对象的指针,该对象标识了流(文件)。
- offset:是相对于 fromwhere 的位移量,以字节为单位。
- origin:定义了 offset 的起始位置,它可以是以下三个值之一:
SEEK_SET
:从文件开头开始计算偏移量。SEEK_CUR
:从当前位置开始计算偏移量。SEEK_END
:从文件末尾开始计算偏移量。如果
fseek
函数执行成功,它将返回0;如果执行失败(例如,当偏移量超出文件大小),则不改变文件指针的位置,并返回非零值。一个常见的
fseek
使用场景是在文件中插入或删除数据。例如,如果你想在文件的特定位置后追加一些内容,你可以使用fseek
将文件指针移动到那个位置,然后写入新的内容。需要注意的是,在使用
fseek
时,要确保对文件的操作符合文件打开模式。例如,以只读模式打开的文件不能使用fseek
来设置写操作的位置。此外,fseek
函数与文本模式和二进制模式的兼容性也是需要注意的,因为在文本模式下,某些特殊的字符(如换行符)可能会被转换,这可能会影响到fseek
的行为。
long int ftell ( FILE * stream );
int main()
{
FILE* pFile;
long size;
pFile = fopen("data.txt", "rb");
if (pFile == NULL)
perror("Error opening file");
else
{
fseek(pFile, 0, SEEK_END); // non-portable
size = ftell(pFile);
fclose(pFile);
printf("Size of data.txt: %ld bytes.\n", size);
}
return 0;
}
void rewind ( FILE * stream );
打开一个流的时候这个流上有2个标记值:
1. 是否遇到文件末尾
2. 是否发生错误
feof 用来检测第一个标记值
ferror 用来检测第二个标记值
文件缓冲区的作用主要是提高数据读写效率和保护硬盘。
文件缓冲区是计算机内存中的一块区域,它用于临时存储从磁盘文件中读取的数据或待写入的数据。以下是文件缓冲区的几个关键作用:
- 减少磁盘I/O操作:由于磁盘的读写速度远低于内存的访问速度,使用缓冲区可以减少对磁盘的直接访问次数。当需要读取文件时,数据先被加载到缓冲区中,程序直接从缓冲区读取数据,而不是每次都去访问物理硬盘。
- 提高数据处理速度:缓冲区使得数据的处理可以在更快的内存中进行,从而提高整个系统的运行效率。例如,在文本编辑器中编辑文档时,实际上是在缓冲区中进行修改,直到用户明确保存文件时,修改才被写回硬盘。
- 统一数据传输速率:缓冲区还用于在不同速率的设备之间传输数据时提供速度适配。比如,它可以协调慢速的硬盘与快速的CPU之间的数据传输速率差异。
- 缓存常用数据:缓冲区可以暂存那些经常被重复使用的数据,避免每次需要时都重新从硬盘加载,这在数据库系统和文件系统中尤为重要。
- 缓冲区刷新策略:缓冲区根据不同的应用场景采取不同的刷新策略,如立即刷新、行刷新或全缓冲刷新等,以确保数据的及时更新和减少数据丢失的风险。
综上所述,文件缓冲区通过在内存中暂存数据来桥接快速和慢速设备之间的速度差异,减少了对硬盘的物理读写次数,从而提升了数据处理的效率和系统的整体性能。
文章浏览阅读4.1k次,点赞2次,收藏4次。社会和科技的不断进步带来更便利的生活,计算机技术也越来越平民化。二十一世纪是数据时代,各种信息经过统计分析都可以得到想要的结果,所以也可以更好的为人们工作、生活服务。电影是生活娱乐的一部分,特别对喜欢看电影的用户来说是非常重要的事情。把计算机技术和影院售票相结合可以更符合现代、用户的要求,实现更为方便的购买电影票的方式。本基于Java Web的在线电影票购买系统采用Java语言和Vue技术,框架采用SSM,搭配MySQL数据库,运行在Idea里。
文章浏览阅读1.8k次。Exception in thread "main" java.lang.NullPointerException at java.util.ArrayList.addAll(ArrayList.java:559) at com.iflytek.epdcloud.recruit.utils.quartz.Acool.main(Acool.java:16)import java.u..._addall(null)
文章浏览阅读4.5k次。public static void main(String[] args) { Calendar todayStart = Calendar.getInstance(); todayStart.set(Calendar.HOUR_OF_DAY, 0); todayStart.set(Calendar.MINUTE, 0); toda..._java 获取某分钟的起止时间戳
文章浏览阅读1.1k次。合适的工作难找?最新的招聘信息也不知道?AI 求职为大家精选人工智能领域最新鲜的招聘信息,助你先人一步投递,快人一步入职!京东 AI 研究院京东 AI 研究院(https://air.jd..._京东计算机视觉实验室
文章浏览阅读2.1k次。Ubuntu18.04安装配置Qt5.15 Ubuntu18.04安装配置Qt5.15 Qt选择下载Qt安装Qt5.15.0配置后记 Qt选择 在官方的声明中,Qt5.15是Qt5.x的最后一个LTS版本,增加了即将在2020年底推出的Qt6的部分新特性,为了之后的新_ubuntu安装qt5.15
文章浏览阅读1.8w次,点赞5次,收藏3次。针对Error: You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings问题的解决使用intelliJ Idea开发django项目,启动 manage.py 测试时,会出现如上所示问题。根据提示,有两种解_project structure->facets->django->
文章浏览阅读2.2k次。rufus 一款好用的linux u盘,光盘刻录工具:下载(点击普通下载中的“立即下载”): http://share.cnop.net/file/1806028-401886318_rufus可以刻录光盘吗
文章浏览阅读142次。Option Explicit OnModule INI 'INICont.bas Ver 1.0+a INI '==================================================================== 'GetIntFromINI( sectionName , keyName , defaultValue, iniPath ) '..._vb.net 读取ini文件 int
文章浏览阅读615次。1 集群的定义集群的出现主要是为了解决单台设备性能不足、效率低下等问题,可以保证业务无中断,总体效率高,适合大型业务。2 集群的分类3 负载均衡集群LBC_lbc在程序中是什么
文章浏览阅读3k次。《文字学概论》作业一、单选题1、原始社会陶器上的图形符号刻划是以( )为代表的。A 仰韶文化 B 马家窑文化 C 良渚文化 D 大汶口文化2、下列各字中不属于象形字的是( )。A十 B小 C羊 D未3、“画成弃物 ,随体诘屈”,是许慎给六书当中的( )所下的定义。A 象形 B 指事 C 假借 D 会意4、下列各字当中形旁为"肉”的是( )。A 肌 B 明 C 钥 D 腾5、“夫” 字是在“大”字之上加一横而成的,这_十小羊未哪一个不是象形字
文章浏览阅读328次,点赞9次,收藏8次。tiny_tds: 简易的Microsoft SQL Server驱动程序 for Rubytiny_tds 是一个小巧且高效的Microsoft SQL Server驱动程序,专为Ruby编程语言设计。它提供了与SQL Server进行交互的能力,可以轻松地执行查询、事务管理以及数据操作。项目简介tiny_tds是一个开源项目,由Rails SQL Server社区开发并维护。该库支持多种...
文章浏览阅读8.6k次。1,基础篇:1.1《SQL基础教程》本书是畅销书《SQL基础教程》第2版,介绍了关系数据库以及用来操作关系数据库的SQL语言的使用方法。书中通过丰富的图示、大量示例程序和详实的操作步骤说明,让读者循序渐进地掌握SQL的基础知识和使用技巧,切实提高编程能力。每章结尾设置有练习题,帮助读者检验对各章内容的理解程度。另外,本书还将重要知识点总结为“法则”,方便读者随时查阅。第2版除了将示例程序更新为对应..._高性能mysql第五版 pdf