前言(可跳过)
在进行大型文件的读写操作时,若采用读打开文件a,再将“a中修改删除位置之前的内容+修改删除的内容+a中修改删除位置之后的内容”保存到文件b,关闭并删除文件a,将文件b改名为与文件a同名的简单办法,即使结果同修改指定位置的数据的方式相同,但程序所占时间片和内存空间都会难以想象的巨大。
作为一个优秀的程序员,这种掩耳盗铃的办法根本不是应该采取的办法,采用追加写入然后替换源文件的方式根本不能代替对指定位置局部修改的功能,我们必须直面问题,怎么将数据写入指定位置,这不是PTA黑盒测试,不能只关注结果。纵使结果相同,但只要实现方式不正确,问题就还没解决。
然而,我查看许多平台上许多相似提问的回答,大多人都采用一些代替方法来解决问题,这并不值得苛责,闻道有先后,术业有专攻,每个程序员都有他们自己不会的内容,这很正常,甚至我的水平比看这篇文章的大多数人都要来得差。但问题是,知之为知之,不知为不知,不会就是不会,不会就不要自负地觉得自己的办法是唯一的办法。有的人只会那些代替办法,还信誓旦旦说没有更好的办法了,我之前差点就以为只有这些替代办法了,没有办法直接对指定文件进行修改。承认自己能力不足很难吗,可能对某些人来说很难,但是不管怎么说,自己能力不足不愿听取他人意见还自负地去误人子弟是不对的。
当然,我也能力也远远不足,以下我所采用的办法也不是最好的办法,就权当我抱砖引玉,希望我的方法能对各位读者有所启发。
具体需求
不同的人有不同的需求,我是在处理二进制文件时所产生的需求,我要求对该二进制文件的制定位置进行读写操作,且要求在未找到该文件的情况下新建文件。
我在查找解决问题的方法中,看到有些人的需求是在文本文件中查找指定数据并修改,在此也一并解决。
解决思路
有些东西解决起来感觉很难,但一旦看到解决办法,啊,就感觉真的好简单。
就像那经典的程序员语句:“卧槽,程序还能这么写!”
这里的思路实现起来其实很简单,但是为什么我当初想了那么久才想到呢T_T
我们要注意到,在C语言标准I/O(输入与输出)库中,fopen()函数的模式字符串如下:
我们发现w写入会清空原文件,a写入只能追加,而+号代表可以读和写,所以其实我们只要采用r+型就可以做到对指定位置的输入了。(看来语文真的很重要)
注意,一定要是r+型(含rb+,rt+)任何其他方式都不行
事实上,ANSI C标准库一直提供更新文件的方式,不过我一直没注意到r+方式也可以写入,并且还是可以在文件中修改删除的那种方式,真的是踏破铁皮无觅处,得来全不费工夫。
不过我的需求还差一点,那就是文件不存在还需新建一个,对此我采用了初始化检查中插入a+的方式。
解决代码
注意:在VS2019环境下的部分实现代码
#include<stdio.h>//由于iostream包含stdio.h,体积过于庞大,故不采用
bool Examination() {
//检查函数
FILE* test;//设置文件指针
errno_t open_return;//文件打开返回值,若返回非0则失败
open_return = fopen_s(&test, "data", "ab+");//以二进制打开程序目录下的data文件,若无则新建
fclose(test);//检索成功,关闭文件
return (bool)open_return;//检查正常
}
int main() {
char Exam_Return = Examination();//检查data文件
if (Exam_Return) {
}//返回1则检查失败
FILE* data;//设置文件指针
errno_t open_return;//文件打开返回值,若返回非0则失败
open_return = fopen_s(&data, "data",