高阶C语言|文件操作——你不知道的文件小秘密

💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习!
👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C语言感兴趣的朋友

文件,究竟是什么鬼?

说到文件,大部分人可能会想:“哎呀,不就是那种看得见摸得着的东西嘛!”没错,文件就是磁盘上的一堆信息,只不过它们的样子不太一样。比如有程序文件(扩展名 .c.exe 什么的)和数据文件(它们存储的是你在程序里使用的数据)。别看这些文件表面平凡,它们的背后可是大有文章。

我们常见的文件有两大类:

  1. 程序文件:这些通常是你的源代码文件(像 .c 后缀的文件),以及编译后产生的目标文件(例如 .obj.exe)。这类文件代表的是程序的执行逻辑和操作。
  2. 数据文件:这些文件是程序运行过程中需要的外部数据,或者是程序执行后的输出结果。

文件本身并不复杂,了解了这些,你就能轻松搞定文件操作。

文件指针——你的文件“朋友”

文件操作不可能不提文件指针。你和文件的每次互动,都得有个“桥梁”——这就是文件指针。它就像是你和文件沟通的一个小助手,通过它,你可以告诉文件“嘿,快给我读点东西”,或者“你可以关机啦”。不信?来看看下面这段代码:

FILE* fp = fopen("myfile.txt", "w");

这个 fp 变量就是文件指针,它让你能够连接到文件 myfile.txt,然后对它进行各种操作。想关上它吗?那就用 fclose 把它“请走”:

fclose(fp);
fp = NULL; // 防止野指针乱来

通过文件指针,你可以在内存中找到文件的相关信息(如文件名、文件状态等),也可以方便地进行读取或写入操作。

文件打开的那些“门道”

打开文件有一堆方式,比如只读、只写、追加等等。就像你去餐厅点菜,有的人喜欢点个“只读的沙拉”,有的人则想要一份“只写的牛排”。不过,要记住,一旦选定了“门道”,就不能乱点其他的了!

打开文件的方式有很多种,主要有以下几种模式:

文件使用方式含义如果指定文件不存在
“r”(只读)为了输入数据,打开一个已经存在的文本文件出错
“w”(只写)为了输入数据,打开一个文本文件建立一个新文件
“a”(追加)向文本文件尾添加数据建立一个新文件
“rb”(只读)为了输入数据,打开一个二进制文件出错
“wb”(只写)为了输出数据,打开一个二进制文件建立一个新文件
”ab“向一个二进制文件尾添加数据出错

例如,你想打开一个文件并向其中写入内容,可以使用以下代码:

#include <stdio.h>
int main ()
{
 FILE * pFile;
 //打开文件
 pFile = fopen ("myfile.txt","w");
 //文件操作
 if (pFile != NULL)
{
  fputs ("fopen example", pFile);
  //关闭文件
  fclose (pFile);
}
 return 0;
}
常用的顺序输入输出函数——让你有条不紊的使用文件
  1. 字符输入函数(fgetc)

    • 函数名称fgetc
    • 适用流:所有输入流
    • 功能fgetc 用于从文件中读取一个字符。无论是从标准输入流(如键盘)还是文件流,它都可以读取字符。
  2. 字符输出函数(fputc)

    • 函数名称fputc
    • 适用流:所有输出流
    • 功能fputc 用于将一个字符写入文件,或者输出到其他流(如标准输出流)。
  3. 文本行输入函数(fgets)

    • 函数名称fgets
    • 适用流:所有输入流
    • 功能fgets 用于从文件中读取一行文本,通常用于处理每行数据时,比 fgetc 更加方便,因为它能读取整行数据。
  4. 文本行输出函数(fputs)

    • 函数名称fputs
    • 适用流:所有输出流
    • 功能fputs 将一行文本写入文件或者输出流,适合写入字符串。
  5. 格式化输入函数(fscanf)

    • 函数名称fscanf
    • 适用流:所有输入流
    • 功能fscanf 是一个格式化输入函数,类似于 scanf,用于从文件中读取格式化的数据(如整数、浮点数、字符串等)。
  6. 格式化输出函数(fprintf)

    • 函数名称fprintf
    • 适用流:所有输出流
    • 功能fprintf 是一个格式化输出函数,类似于 printf,可以将格式化的输出写入文件或其他流。
  7. 二进制输入(fread)

    • 函数名称fread
    • 适用流:文件
    • 功能fread 用于从文件读取二进制数据,这与从文件读取文本数据不同,适用于处理二进制文件。
  8. 二进制输出(fwrite)

    • 函数名称fwrite
    • 适用流:文件
    • 功能fwrite 用于将二进制数据写入文件,常用于文件格式为二进制的应用。
流的含义——数据的“大马路”

图中的流指的是数据流向的方向,简而言之,流就像一个通道,通过它,程序可以与不同的数据源(如文件、标准输入/输出、网络)进行数据交换。

  • 标准输入流(stdin):表示从键盘或者其他输入设备获取数据。类型为 FILE*
  • 标准输出流(stdout):表示向屏幕或终端输出数据,也常用于程序的输出。类型为 FILE*
  • 标准错误流(stderr):专门用来输出错误信息,通常输出到屏幕,帮助调试和记录错误。类型为 FILE*

这些流在 C 语言中有默认的设置,你可以使用它们来与程序外部的数据进行交互。

fseek和ftell——让你随意“跳跃”文件

如果文件指针是你和文件之间的“通信员”,那 fseekftell 就是你用来“调皮捣蛋”的工具。想要快速跳转到文件的某个位置?fseek 就是你的“跳跃王者”。它能让你精准地告诉文件:“嘿!快点,跳到那个地方!”

fseek(fp, 100, SEEK_SET); // 跳到文件的第100个字节

如果你是个数字控,ftell 会告诉你文件指针现在在第几字节,完美配合使用,你就能像个文件专家一样随心所欲地翻阅文件。

long int position = ftell(fp);
printf("Current position: %ld\n", position);

有了它们,文件就像一张无穷无尽的地图,而你是那个能够自由穿梭的探险家。

rewind——倒带重放,穿越回文件的“起点”

偶尔我们会在文件中“迷失”,对吧?但别担心,rewind 函数会帮你找回“方向感”,它能把文件指针迅速拉回文件的起点,仿佛你按下了“倒带”按钮,所有操作都能重新开始。

rewind(fp); // 把文件指针拉回到开头

是不是感觉像是时光机?你可以重新阅读文件的内容,或者再次执行某些操作,完全不需要重开一个新文件。

文件缓冲区——它的幕后“神操作”

当你和文件在“亲密互动”的时候,文件并不总是立刻回应你。为什么?因为文件背后有一个隐秘的“缓冲区”,这个缓冲区可不是随便的东西,它像是个内存仓库,存储着所有待操作的数据。系统会先把数据传递到缓冲区,再从缓冲区读取或写入磁盘。你可能觉得它不够直接,但这也让整个过程更高效。

不过,既然是“幕后工作”,它就不喜欢被打扰。如果你不小心忽略了这个缓冲区的刷新(比如直接关闭文件),数据可能就会丢失。所以,记得及时调用 fflush 来刷新缓冲区,确保文件内容没跑掉:

fflush(fp); // 刷新缓冲区,确保数据写入文件
文件读取结束的判定——别让它“赖账”

当你和文件打交道时,总会遇到“结束”的问题。你是不是也曾经遇到过文件读到一半就突然消失的情况?别怕,文件结束有专门的信号,比如 EOF(文件结束符)或者 NULL(读取错误)。当你遇到这些信号时,表示文件已经结束或发生了错误,赶紧收拾收拾,不要继续“纠缠”下去。

文本文件的读取可以使用 fgetc 来判断是否遇到 EOF,或者用 fgets 判断返回值是否为 NULL,这都能告诉你文件是否正常结束。

对于二进制文件,我们则需要注意 fread 的返回值,它能告诉你是否成功读取了预期的字节数。

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
  int c; // 注意:int,非char,要求处理EOF
  FILE* fp = fopen("test.txt", "r");
  if(!fp) {
    perror("File opening failed");
    return EXIT_FAILURE;
 }
 //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
  while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
 {
   putchar(c);
 }
 //判断是什么原因结束的
  if (ferror(fp))
    puts("I/O error when reading");
  else if (feof(fp))
    puts("End of file reached successfully");
  fclose(fp);
}
总结:文件不再神秘

文件操作的世界其实并没有你想象的那么复杂。只要掌握了文件打开、读写、关闭的基本技巧,再加上对 fseekrewind 这些“小工具”的灵活运用,你就能轻松自如地管理你的文件了。

所以,下次当你面对文件时,不要再紧张了!只要记得好好地与它互动,文件也会变成你忠实的小伙伴,陪你一起完成各种任务,轻松搞定所有挑战。


标题“51单片机通过MPU6050-DMP获取姿态角例程”解析 “51单片机通过MPU6050-DMP获取姿态角例程”是一个基于51系列单片机(一种常见的8位微控制器)的程序示例,用于读取MPU6050传感器的数据,并通过其内置的数字运动处理器(DMP)计算设备的姿态角(如倾斜角度、旋转角度等)。MPU6050是一款集成三轴加速度计和三轴陀螺仪的六自由度传感器,广泛应用于运动控制和姿态检测领域。该例程利用MPU6050的DMP功能,由DMP处理复杂的运动学算法,例如姿态融合,将加速度计和陀螺仪的数据进行整合,从而提供稳定且实时的姿态估计,减轻主控MCU的计算负担。最终,姿态角数据通过LCD1602显示屏以字符形式可视化展示,为用户提供直观的反馈。 从标签“51单片机 6050”可知,该项目主要涉及51单片机和MPU6050传感器这两个关键硬件组件。51单片机基于8051内核,因编程简单、成本低而被广泛应用;MPU6050作为惯性测量单元(IMU),可测量设备的线性和角速度。文件名“51-DMP-NET”可能表示这是一个与51单片机及DMP相关的网络资源或代码库,其中可能包含C语言等适合51单片机的编程语言的源代码、配置文件、用户手册、示例程序,以及可能的调试工具或IDE项目文件。 实现该项目需以下步骤:首先是硬件连接,将51单片机与MPU6050通过I2C接口正确连接,同时将LCD1602连接到51单片机的串行数据线和控制线上;接着是初始化设置,配置51单片机的I/O端口,初始化I2C通信协议,设置MPU6050的工作模式和数据输出速率;然后是DMP配置,启用MPU6050的DMP功能,加载预编译的DMP固件,并设置DMP输出数据的中断;之后是数据读取,通过中断服务程序从DMP接收姿态角数据,数据通常以四元数或欧拉角形式呈现;再接着是数据显示,将姿态角数据转换为可读的度数格
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值