文件操作介绍(下)

简介: 文件操作介绍(下)

文件的随机读写

fseek

根据文件指针的位置和偏移量来定位文件指针。
例子:

int fseek ( FILE * stream, long int offset, int origin );
/* fseek example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  pFile = fopen ( "example.txt" , "wb" );
  fputs ( "This is an apple." , pFile );
  fseek ( pFile , 9 , SEEK_SET );
  fputs ( " sam" , pFile );
  fclose ( pFile );
  return 0;
}

fseek函数是C语言中的一个标准库函数,用于在文件中定位文件指针的位置。
它的原型如下:

int fseek(FILE *stream, long int offset, int whence);

其中,stream是一个指向要进行定位的文件的指针,offset是要设置的偏移量,表示距离whence位置的偏移量,whence表示相对于何处进行定位的标志。

whence参数可以取以下三个值:

SEEK_SET:从文件开头开始计算偏移量。

SEEK_CUR:从当前位置开始计算偏移量。

SEEK_END:从文件末尾开始计算偏移量。

fseek函数用于将文件指针定位到指定位置,以便进行后续的读取或写入操作。通过指定偏移量和whence参数,可以实现不同的定位需求,例如从文件开头处跳过固定长度的数据,或者从当前位置向后移动指定偏移量。

下面是一个使用fseek函数的示例:

#include <stdio.h>
int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp != NULL) {
        fseek(fp, 5, SEEK_SET);  // 设置文件指针跳过前5个字节
        char ch;
        fscanf(fp, "%c", &ch);
        printf("Character: %c\n", ch);
        fclose(fp);
    }
    return 0;
}

在这个示例中,我们打开了一个名为"example.txt"的文件,并使用fseek函数将文件指针定位到距离文件开头5个字节处。然后,我们使用fscanf函数读取下一个字符,并将其输出到控制台。

假设文件中的内容为:“Hello, world!”,那么输出结果如下:

Character: ,

通过调用fseek函数进行文件定位,我们可以控制文件指针的位置,以便进行读取或写入操作。

ftell是C语言中的标准库函数,用于获取文件指针当前位置相对于文件起始位置的偏移字节数。它的原型如下:

long ftell(FILE *stream);

其中,stream是一个指向已打开文件的指针。

ftell函数返回一个long类型的值,表示当前位置相对于文件起始位置的偏移字节数。如果函数调用失败,它将返回-1。

下面是一个使用ftell函数的简单示例:

#include <stdio.h>
int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp != NULL) {
        // 获取文件指针位置
        long position = ftell(fp);
        printf("Current position: %ld\n", position);
        fclose(fp);
    }
    return 0;
}

在这个示例中,我们打开了一个名为"example.txt"的文件,并使用fopen函数创建了一个文件指针fp。然后,我们使用ftell函数获取当前文件指针的位置,并将其输出到控制台。

ftell函数通常与fseek函数联合使用,可以用来定位文件中的特定位置,并支持在文件中进行随机读写操作。

需要注意的是,ftell函数返回的偏移字节数类型是long,具体字节数的上限取决于编译环境中的long类型的大小。

rewind函数是C语言中的一个标准库函数,用于将文件指针重新定位到文件的起始位置。它的原型如下:

void rewind(FILE *stream);

其中,stream是一个指向要重新定位的文件的指针。

rewind函数将文件指针重新设置为文件的起始位置,以便重新读取文件或执行其他操作。

下面是一个使用rewind函数的简单示例:

#include <stdio.h>
int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp != NULL) {
        char ch;
        // 读取文件中的一个字符
        fscanf(fp, "%c", &ch);
        printf("Character: %c\n", ch);
        // 将文件指针重新定位到文件起始位置
        rewind(fp);
        // 再次读取文件中的一个字符
        fscanf(fp, "%c", &ch);
        printf("Character: %c\n", ch);
        fclose(fp);
    }
    return 0;
}

在这个示例中,我们打开了一个名为"example.txt"的文件,并使用fscanf函数读取文件中的一个字符,并将其输出到控制台。

然后,我们调用rewind函数将文件指针重新定位到文件的起始位置。

最后,我们再次使用fscanf函数读取文件中的一个字符,并将其输出到控制台。由于调用了rewind函数,所以我们重新读取到文件中的第一个字符。

文本文件和二进制文件

根据数据的组织形式,数据文件被称为文本文件或者二进制文件。

数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。

一个数据在内存中是怎么存储的呢?

字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。

如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而

二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。

#include <stdio.h>
int main()
{
 int a = 10000;
 FILE* pf = fopen("test.txt", "wb");
 fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
 fclose(pf);
 pf = NULL;
 return 0;
 }

文件读取结束的判定

被错误使用的feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。

而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

  1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
    例如:
    fgetc 判断是否为 EOF .
    fgets 判断返回值是否为 NULL .
  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
    例如:
    fread判断返回值是否小于实际要读的个数。

文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

#include <stdio.h>
#include <windows.h>
//VS2013 WIN10环境测试
int main()
{
 FILE*pf = fopen("test.txt", "w");
 fputs("abcdef", pf);//先将代码放在输出缓冲区
 printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
 Sleep(10000);
 printf("刷新缓冲区\n");
 fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
 //注:fflush 在高版本的VS上不能使用了
 printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
 Sleep(10000);
 fclose(pf);
 //注:fclose在关闭文件的时候,也会刷新缓冲区
 pf = NULL;
 return 0;
}

从上面的代码运行结果可以得到:因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题。

最后学完文件操作,小伙伴可以尝试一下将通讯录系统再次改造,把信息保存在桌面上的文本文档试一下吧!

目录
相关文章
|
应用服务中间件 Linux nginx
CentOS下Nginx环境的搭建及进阶配置(安装篇)
Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。 本文主要讲解如何在CentOS搭建及配置Nginx
598 0
CentOS下Nginx环境的搭建及进阶配置(安装篇)
|
10月前
|
人工智能 数据可视化 数据挖掘
【产品】G 端产品经理
G端产品经理在政府数字化转型中扮演着关键角色,连接政府需求与技术实现。他们负责挖掘需求、规划方案、推动跨部门协作,并监督项目进展。具体职责包括需求调研、产品规划与设计、原型制作、文档撰写及交互与视觉设计等。面对复杂多变的需求、快速更新的技术和严格的项目验收,G端产品经理需不断提升专业技能,以适应挑战并推动政府治理体系现代化。
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的蛋糕商城管理系统
基于Java+Springboot+Vue开发的蛋糕商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的蛋糕商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
350 3
基于Java+Springboot+Vue开发的蛋糕商城管理系统
|
11月前
|
SQL 数据可视化 数据挖掘
让项目数据更有说服力:五款必备数据可视化管理工具推荐
在现代企业管理中,数据是决策的重要依据。有效的数据可视化工具能帮助项目经理快速洞察项目进展、评估风险、优化资源配置。本文推荐五款必备的数据可视化管理工具,包括板栗看板、Power BI、Tableau、Google Data Studio和Qlik Sense,从功能、易用性和优缺点等方面进行全面评析,帮助您将数据转化为行动,推动项目高效前行。
368 4
|
12月前
|
机器学习/深度学习 数据可视化 大数据
驾驭股市大数据:Python实战指南
【10月更文挑战第1天】随着信息技术的发展,投资者现在能够访问到前所未有的海量金融数据。本文将指导您如何利用Python来抓取当前股市行情的大数据,并通过分析这些数据为自己提供决策支持。我们将介绍从数据获取到处理、分析以及可视化整个流程的技术方法。
585 2
|
Kubernetes 监控 API
Rancher 系列文章 -Rancher v2.6 使用脚本实现导入集群
Rancher 系列文章 -Rancher v2.6 使用脚本实现导入集群
|
机器学习/深度学习 人工智能 DataWorks
云上AI服务,中国最佳
云上AI服务,中国最佳
296 10
|
Cloud Native Devops 持续交付
探索云原生架构:未来企业技术演进的必由之路
随着数字化转型的浪潮席卷全球,企业正逐步将目光转向云原生架构,以期实现更高效、灵活且可扩展的IT服务。本文深入探讨了云原生的核心概念,包括容器化、微服务、持续集成与持续部署等,并阐述了这些技术如何共同促进现代企业的快速发展。同时,通过分析具体案例,展示了云原生在实际应用中带来的效益,以及企业在采纳云原生路径时可能面临的挑战和解决策略。
|
缓存 负载均衡 数据库
优化后端性能:提升Web应用响应速度的关键策略
在当今数字化时代,Web应用的性能对于用户体验至关重要。本文探讨了如何通过优化后端架构和技术手段,提升Web应用的响应速度。从数据库优化、缓存机制到异步处理等多个方面进行了深入分析,并提出了一系列实用的优化策略,以帮助开发者更好地应对日益增长的用户访问量和复杂的业务需求。
759 28
|
编解码 前端开发 Java
【推荐100个unity插件之12】UGUI的粒子效果(UI粒子)—— Particle Effect For UGUI (UI Particle)
【推荐100个unity插件之12】UGUI的粒子效果(UI粒子)—— Particle Effect For UGUI (UI Particle)
1358 0