更改文件内容(1)

更改文件部分内容(1)

本文使用c语言实现更改文件部分内容

更改一个已经存在的文件的部分内容是比较困难的,原因是对已经存在的文件进行的操作都是覆盖操作,没有插入和删除操作,因此理论上来说,你只能够增大或者维持文件大小不变,而不能缩小文件,要实现更改文件部分内容的目标,共有两种方法:创建临时文件作为中转创建缓冲区作为中转

创建临时文件作为中转

使用到的函数

  • FILE* fopen(const char* fileName, const char* mode)

    需要头文件#include<stdio.h>

    fopen()打开文件,如果用的是w+mode的话,当打开一个已存在的文件,会清空其中内容;如果文件不存在,会创建一个空白文件,符合我们创建临时文件的要求。

    创建临时文件fopen(fileName,"w+")

    要打开修改的文件,就不能用w+mode,因为会清空内容。可以选用r+或者r来进行操作。

    打开修改文件fopen(fileName,"r+")或者fopen(fileName,"r")

  • int _access(const char* path, int mode)

    需要头文件#include<io.h>

    注意这个函数是windows下检验的函数,如果要linux下检验的函数,对应的是access

    这个函数可以检验文件是否存在,只要设置mode=00就可以。如果文件存在,返回0,文件不存在,返回-1。

    这个是用来和创建临时文件相互配合,创建临时文件之前先判断当前目录中是否有同名文件,避免覆盖有用的文件内容

  • int fgetc(FILE* stream)

    需要头文件#include<stdio.h>

    这个函数返回stream对应的文件中的一个字符,同时将文件流的指针后移。

    利用这个函数可以对文件中的字符进行逐个遍历。

  • char* fgets(char* str, int num, FILE* stream)

    需要头文件#include<stdio.h>

    这个函数读取一行数据或者是最多num-1个字符,放入str中,注意,该函数会自动添加尾0。

    同时该函数只有当输入遇到问题的时候,返回值才会为NULL,就算这次读入遇到了文件终止符,只要成功读入了内容,那么返回值就不会为NULL,因此可以用fgets() == NULL来判断读取全部有用信息。

  • int fputc(int character, FILE* stream)

    stream代表的文件流中输入一个字符,同时文件指针自动前移。

  • int fprintf(FILE* stream, const char* format, ...)

    这个函数类似于正常的printf,只是前面多了一个FILE*参数,表示是向对应的文件进行输入。

  • size_t fread(void* ptr, size_t size, size_t count, FILE* stream)

    这个函数从文件中读取count * size的字节数内存,存入ptr中,注意,该函数读取的字节不会自动附加尾零。

    该函数通常用于整体读取

  • size_t fwrite(void* ptr, size_t size, size_t count, FILE* stream)

    这个函数用于向文件中存储count * size的字节数内存,从ptr中获取,同样的也不会因为尾零而终止。

    该函数通常用于整体写入

  • int remove(cont char* filename)

    删除文件filename,用于删除待修改的文件

  • int rename(const char* oldname, const char* newname)

    oldname文件名称改为newname,用于把临时文件改为原来的文件名称

实现逻辑

创建临时文件

File* create_tmp()   //创建临时文件(只是为了方便写成了个函数,真正操作的时候要放在主函数中,因为要用到临时文件名称)
{
	do   //生成合适的临时文件名称
	{
		char tmp[200];  //创建一个200个字节的长度存储临时文件名
		for(int i = 0; i < 100; i++)
	    	tmp[i] = rand() % 26 + 'a';  //用随机数创建一个文件名,保证尽可以能不重复
		tmp[100] = '\0';
		strcat(tmp,".tmp");   //给临时文件赋一个后缀。
	} while(access(tmp,0) >= 0)   //只要当前文件名存在,就重新生成
	File* fp = fopen(tmp,"w+");   //如果fp为NULL,说明创建或者打开失败,这个可以留给主函数判断
    return fp;
}

对修改文件进行处理

这里以清除注释为例,假设#后面的都是注释,那么我想把注释内容全部删掉,就可以一行一行的进行处理

void check_file(const char* fileName)  //对文件内容进行处理
{
	FILE* fp, *tmpFp;   //创建两个文件指针,fp指向待修改文件,tmpFp指向临时文件。
	fp = fopen(fp,"r");
	if(fp == NULL)   //待修改文件打开失败
	{
		printf("文件%s打开失败\n",fileName);
		return;   //程序终止
	}
	do   //生成合适的临时文件名称
	{
		char tmp[200];  //创建一个200个字节的长度存储临时文件名
		for(int i = 0; i < 100; i++)
	    	tmp[i] = rand() % 26 + 'a';  //用随机数创建一个文件名,保证尽可以能不重复
		tmp[100] = '\0';
		strcat(tmp,".tmp");   //给临时文件赋一个后缀。
	} while(access(tmp,0) >= 0)   //只要当前文件名存在,就重新生成
	tmpFp = fopen(tmp,"w+");   //如果fp为NULL,说明创建或者打开失败,这个可以留给主函数判断
	if(tmpFp == NULL)  //临时文件创建失败判断
	{
		printf("临时文件创建失败\n");
		return;
	}
	char lineStr[1024];   //假设一行最多1024字节
	while(fgets(lineStr,1024,fp))  //对文件内容进行处理
	{
		get_index(lineStr);  //假设get_index删除lineStr中#之后内容
		fprintf(tmpFp,"%s",lineStr);   //将更改后的内容加入临时文件之中
	}  //持续此操作,直到文件中内容全部被遍历
	fclose(fp);   //把两个文件指针关闭
	fclose(tmpFp);

	remove(fileName);   //把原来的文件删除
	rename(tmp,fileName);  //把临时文件更改为源文件的名称
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值