【C语言_文件操作】

简介

这是《操作系统进阶》课上的project0的project_b部分内容。主要是练习用C语言进行文件的相关操作。这个project的要求是:

编写一个名为kv.c的程序,它是对持久键值对存储系统(比如FaceBook的RocksDB 和 Google的LevelDB )的简单模拟实现,这里用file来实现持久性的要求,即对file进行一系列操作。要求实现以下指令:

  • put:格式为 p,key,value,其中 key 是整数,值为任意字符串(其中没有逗号)。向file中插入键值对。
  • get:格式为 g,key,其中 key为整数。如果存在该键,系统应打印出该键,key,value,后跟换行符 (\n)。如果不存在,则在找不到 K 形式的行上单独打印一条错误消息,其中 K 是键的实际值,即某个整数。
  • delete:格式为 d,key,它要么删除相关的键值对(并且不打印任何内容),要么不这样做(并且打印 K,其中 K 是键的实际值,即某个整数)。
  • clear:格式为 c。此命令只是从数据库中删除所有键值对。
  • all:格式为 a。此命令按任意顺序打印出数据库中的所有键值对,每行一个键值对,每个键和值用逗号分隔。

例:在Linux上运行kv文件中的put指令

prompt> ./kv 
prompt> ./kv p,10,remzi
prompt> ./kv p,20,andrea p,40,someotherperson

结果会产生一个file,其内容如下

prompt> cat database.txt
20,andrea
40,someotherperson
prompt>

运行get指令及其结果:

prompt> ./kv g,10
10,remzi
prompt>

注意:对潜在错误的处理:

  • 错误指令:如果命令行指定了错误的命令,例如,不是p,g,a,c或d的东西,请在一行上打印出警告错误命令,并继续处理命令行的其余部分;重要的是,不要退出。
  • 意外错误:在任何意外的错误条件下,例如 malloc() 失败或无法成功打开文件,请打印出有用的错误消息并退出。

以下是我写的代码,由于时间有限没有来得及优化,只测试了部分数据,如有bug欢迎指正。后续有时间再来优化一下。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define M 100
struct data{
	char c[10];
	char key[10];
	char value[M];
};
int main()
{
	FILE *fp;
	fp= fopen("file.txt","w+");//创建文件
	if(fp==NULL)
	{
		printf("文件创建错误");
		return(-1); 
	}
	
	char instruction[M]={0};
	while(scanf("%s",instruction)!=EOF)
	{
		struct data inst;
		memset(inst.c,0,10);
		memset(inst.key,0,10);
		memset(inst.value,0,M);
		char *buf;
		buf=instruction;
		char*token;
		int i=0;

		int j=0,k=0;
		while(instruction[i]!='\0')//分割指令 
		{
			j=0;
			k++;
			while(instruction[i]!=','&&instruction[i]!='\0')
			{
				if(k==1)
				{
					inst.c[j++]=instruction[i];
					i++;
				}
				if(k==2)
				{
					inst.key[j++]=instruction[i];
					i++;
				}
				if(k==3)
				{
					inst.value[j++]=instruction[i];
					i++;
				}
			}
			i++;
		}
		
		if(strcmp(inst.c,"p")==0)//put指令 
		{
			fp= fopen("file.txt","a");//向文件写入但不覆盖 
			if(fp==NULL)
			{
				printf("打开文件错误");
				return(-1);
			}
			fprintf(fp,"%s",inst.key);
			fprintf(fp,"%s",",");
			fprintf(fp,"%s\n",inst.value);
			fclose(fp);
		}
		
		else if(strcmp(inst.c,"g")==0)//get指令 
		{
			char line[M]={0};
			fp= fopen("file.txt","rt");
			if(fp==NULL)
			{
				printf("打开文件错误");
				return(-1);
			}
			while(1)
			{
				if(EOF == fscanf(fp,"%s",line))
				{
					printf("%d not found\n",atoi(inst.key));
					break;
				}
				//printf("%s",line);
				int temp=0,ans=0,t=0;
				ans=atoi(inst.key);
				while(line[t]!=','&&line[t]!='\0')
				{
					temp*=10;
					temp+=(line[t]-'0');
					t++;
				}
			//	printf("line:%s\n",line);
			//	printf("temp:%d\n",temp);
				if(temp==ans)
				{
					printf("%s\n",line);
					break;
				}
			}
			fclose(fp);
		} 
		
		else if(strcmp(inst.c,"d")==0)//delete指令
		{
			char lin[M]={0};
			fp= fopen("file.txt","r+");
			FILE*fp1= fopen("temp.txt","w+");
			if(fp==NULL||fp1==NULL)
			{
				printf("打开文件错误");
				return(-1);
			}
			int flg=0;
			while(1)
			{
				if(EOF == fscanf(fp,"%s",lin))
				{
					if(flg==0)
					{
						printf("d:%d not found\n",atoi(inst.key));
					}
					
					break;
				}
				int temp=0,ans=0,t=0;
				ans=atoi(inst.key);
				while(lin[t]!=','&&lin[t]!='\0')
				{
					temp*=10;
					temp+=(lin[t]-'0');
					t++;
				}
			//	printf("line:%s\n",line);
			//	printf("temp:%d\n",temp);
				if(temp==ans)
				{
					flg=1;
				}
				if(temp!=ans)//不是要删的内容就写入temp 
				{
					//printf("%s\n",line);
					fwrite(lin, sizeof(lin),1, fp1);
				//	break;
				}
			}
			fclose(fp);
			fclose(fp1);
			
			//remove("file.txt");
		//	rename("temp.txt","file.txt"); 出现了错误 不懂 
		    fp=fopen("file.txt","w+");//刷新文件 
		    fp1=fopen("temp.txt","r");
			while(fread(lin,sizeof(lin),1,fp1))
			{
				fwrite(lin, sizeof(lin), 1, fp);
			 } 
		    fclose(fp);
			fclose(fp1); 
		} 
		
		else if(strcmp(inst.c,"c")==0)//clear指令 
		{
			fp= fopen("file.txt","w");
			//只要以 可写 的方式打开文件,就能将这个文件清空
			if(fp==NULL)
			{
				printf("打开文件错误");
				return(-1);
			}
		}
		
		else if(strcmp(inst.c,"a")==0)//all指令
		{
			char Lin[M]={0};
			fp=fopen("file.txt","rt");//权限问题要注意 
		//	printf("test\n");
		/*	while(fread(Lin,sizeof(Lin),1,fp))
			{
				printf("%s\n",Lin);
			} */
			while(1)
			{
				if(EOF == fscanf(fp,"%s",Lin))
				{
					break;
				}
				printf("%s\n",Lin);
			}
			fclose(fp);
		 } 
		 
		 else{
		 	printf("Bad command\n");
		 	continue;
		 }
	}
	fclose(fp);
 } 

之前没写过C语言的文件操作,边查资料边完成了。这个例子对文件操作的运用还是很有参考意义的,故记录一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值