⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delete.c

📁 一个用C编写的简单的关系数据库系统
💻 C
字号:
void Delete(DBF * dbf_name, char * commond, FILE ** opened_fp)
{
	RecUnion rec[MAX_FILED_COUNT]; 
	RecUnion * recIn = (RecUnion *)malloc(sizeof(RecUnion));
	RecUnion * tempRec = (RecUnion *)malloc(sizeof(RecUnion));

	char yes = 'n';

	int q = 0;
	int i = 0;
	int xiaoshu = FALSE;
	int tempInt = 0;
	int fpi;
	int op = -1;/*记录关系运算符类型*/
	int isString = FALSE;/*记是否为字符串型*/
	int Delete = FALSE;/*标记是否要进行删除操作*/
	int dCount = 0;/*记录总的纪录删除数*/
	int pos1 = -1;/*记录关系运算符第一个运算对象,字段的位置*/
	int pos2 = -1;/*关系运算符第二个运算对象,如果是字段的话记录字段的位置*/
	int type1 = -1;/*记录关系运算符第一个运算对象,字段的类型*/
	int type2 = -1;/*关系运算符第二个运算对象,如果是字段的话记录字段的类型*/
	int offset1 = 0;/*记录关系运算符第一个运算对象,字段的长度*/
	int offset2 = 0;/*关系运算符第二个运算对象,如果是字段的话记录字段的长度*/
	int q1 = -1;/*记录关系运算符第一个运算对象,字段的字段号*/
	int q2 = -1;/*如果关系运算符第一个运算对象为字段则记下其字段号*/
	int compare = ERROR;

	unsigned j = 0;

	float div = 1;
	float tempFloat = 0;
	
	commond = strtok(commond," ");
	commond = strtok(NULL," ");

	fpi = dbf_name->dhID;

	if (strcmp(dbf_name->dhName,"\0") == 0)
	{
		puts("	您还没有打开过文件,当前文件为空!!!");
		return;
	}
	if (dbf_name->dhRecCount <= 0)
	{
		puts("	表中没有记录!!!");
		return;
	}
	fseek(opened_fp[fpi],sizeof(DBF),0);
	if (commond == NULL)/*删除的是当前记录*/
	{
		fseek(opened_fp[fpi],dbf_name->dhRecNO*dbf_name->dhRecLen,1);
		/*判断当前指针是否文件结尾
		if (feof(opened_fp[fpi]))
		{
			fseek(opened_fp[fpi],-dbf_name->dhRecLen,1);
		}*/
		ShowRec(opened_fp[fpi],dbf_name,recIn);
		/*确定删除*/
		printf("\n	are you sure to delete the record?(Y/N)");
		scanf("%c",&yes);
		if (yes == 'n' || yes == 'N')
			return;
		/*执行删除操作*/
		dCount++;
		while (!eof(dbf_name->dhHandle))
		{
			ReadRec(opened_fp[fpi],dbf_name,rec);
			fseek(opened_fp[fpi],-dbf_name->dhRecLen,2);
			WriteRec(opened_fp[fpi],dbf_name,rec);
			fflush(opened_fp[fpi]);
			if (feof(opened_fp[fpi]))
				break;
			fseek(opened_fp[fpi],dbf_name->dhRecLen,1);
		}
		if (dbf_name->dhRecNO > 0)
			dbf_name->dhRecNO--;
	}
	else /* delete 操作中有条件*/
	{
		/*读条件中关系运算符的第一个运算对象*/
		for (q=0; q<dbf_name->dhFieldCount; q++)
			if (strcmpi(dbf_name->dbf_struct[q].dhFieldName,commond) == 0)
			{
				pos1 = dbf_name->dbf_struct[q].dhFieldPos;
				type1 = dbf_name->dbf_struct[q].dhFieldType;
				offset1 = dbf_name->dbf_struct[q].dhFieldLen;
				q1 = q;
				break;
			}
		if (pos1 == -1)
		{
			printf("	该关系不存在字段 %s\n",commond);
			return;
		}
		commond = strtok(NULL," ");
		/*读关系运算符*/
		if (commond == NULL)
		{
			puts("	命令格式错误,请输入关系运算符");
			return;
		}
		if (strcmpi(commond,"<") == 0)
			op = LT;
		else if (strcmpi(commond,"<=") == 0)
			op = LE;
		else if (strcmpi(commond,"=") == 0)
			op = EQ;
		else if (strcmpi(commond,">") == 0)
			op = GT;
		else if (strcmpi(commond,">=") == 0)
			op = GE;
		else if (strcmpi(commond,"<>") == 0)
			op = NE;
		else
		{
			puts("	输入的关系运算符错误!!!");
			return; 
		}
		/*读关系运算符的第二个比较对象*/
		commond = strtok(NULL," ");
		if (commond == NULL)
		{
			puts("	命令格式错误,请输入关系运算符的下个运算对象");
			return;
		}
		/*判断第二个运算对象类型,并记录其值*/
		if ((commond[0] == '0') && (strlen(commond) > 1))
		{	
			isString = TRUE;
			type2 = String;
		}
		else
		{
			for (j=0; j<strlen(commond); j++)
			{
				if (isdigit(commond[j]))
				{
					tempFloat = tempFloat * 10 + (int)commond[j] - 48;
					tempInt = tempInt * 10 + (int)commond[j] - 48;
					if (xiaoshu == TRUE)
						div *= 10;
				}
				else if (commond[j] == '.')
				{
					if (xiaoshu == TRUE)
					{
						isString = TRUE;
						break;
					}
					xiaoshu = TRUE;
				}
				else
				{
					isString = TRUE;
					type2 = String;
					break;
				}
			}
		}
		if (isString)
		{
			tempRec->string = (char *)malloc(strlen(commond) * sizeof(char));
			strcpy(tempRec->string,commond);
			/*如果关系运算符的第二个对象为字段名,用pos2记录其偏移位置*/
			for (q=0; q<dbf_name->dhFieldCount; q++)
			{
				if (strcmpi(dbf_name->dbf_struct[q].dhFieldName,commond) == 0)
				{
					pos2 = dbf_name->dbf_struct[q].dhFieldPos;
					type2 = dbf_name->dbf_struct[q].dhFieldType;
					offset2 = dbf_name->dbf_struct[q].dhFieldLen;
					q2 = q;
					break;
				}
			}
			/*free(tempRec->string);
			type2 = String;*/
		}
		else if (xiaoshu)
		{
			tempRec->floatType = tempFloat / div;
			type2 = Float;
		}
		else
		{
			tempRec->intType = tempInt;
			type2 = Int;
		}
		/*进行比较*/
		printf("\n	are you sure to delete the records?(Y/N)");
		scanf("%c",&yes);
		if (yes == 'n' || yes == 'N')
		{
			return;
		}
		for (i=0; i<dbf_name->dhRecCount;i++)
		{
			fseek(opened_fp[fpi],pos1,1);
			switch (type1) {
			case Int:
				fread(recIn,sizeof(int),1,opened_fp[fpi]);
				break;
			case Float:
				fread(recIn,sizeof(float),1,opened_fp[fpi]);
				break;
			case String:
				recIn->string = (char *)malloc(dbf_name->dbf_struct[q1].dhFieldLen * sizeof(char));
				fread(recIn->string,dbf_name->dbf_struct[q1].dhFieldLen,1,opened_fp[fpi]);
				recIn->string[dbf_name->dbf_struct[q1].dhFieldLen] = '\0';
				break;
			default:
				break;
			}
			fseek(opened_fp[fpi],-offset1-pos1,1);
			/*如果第二个运算对象是某个字段,则取出该字段的数据到tempRec*/
			if (pos2 != -1)
			{
				fseek(opened_fp[fpi],pos2,1);
				switch (type2) {
				case Int:
					fread(tempRec,sizeof(int),1,opened_fp[fpi]);
					break;
				case Float:
					fread(tempRec,sizeof(float),1,opened_fp[fpi]);
					break;
				case String:
					tempRec->string = (char *)malloc(dbf_name->dbf_struct[q2].dhFieldLen * sizeof(char));
					fread(tempRec->string,dbf_name->dbf_struct[q2].dhFieldLen,1,opened_fp[fpi]);
					tempRec->string[dbf_name->dbf_struct[q2].dhFieldLen] = '\0';
					break;
				default:
					break;
				}
				fseek(opened_fp[fpi],-offset2-pos2,1);
			}
			/*比较看是否满足删除条件*/
			compare = Compare(recIn,tempRec,type1,type2);
			if (compare == ERROR)
			{
				return;
			}
			switch (op) {
			case LT:
				if (compare == LT)
				{
					Delete = TRUE;
					dCount++;
				}
				break;
			case LE:
				if ((compare == LT) || (compare == EQ))
				{
					Delete = TRUE;
					dCount++;
				}
				break;
			case EQ:
				if (compare == EQ)
				{
					Delete = TRUE;
					dCount++;
				}
				break;
			case GT:
				if (compare == GT)
				{
					Delete = TRUE;
					dCount++;
				}
				break;
			case GE:
				if ((compare == GT) || (compare == EQ))
				{
					Delete = TRUE;
					dCount++;
				}
				break;
			case NE:
				if (compare != EQ)
				{
					Delete = TRUE;
					dCount++;
				}
				break;
			default:
				puts("ERROR");
				return;
				break;
			}/*end of switch*/
			/*if (recIn->string != NULL)
			{
				free(recIn->string);
				recIn = NULL;
			}
			if (tempRec->string != NULL)
			{
				free(tempRec->string);
				tempRec = NULL;
			}*/
			if (!Delete && (dCount > 0))/*说明上一条记录不符合删除条件且以上有记录要删除*/
			{
				ReadRec(opened_fp[fpi],dbf_name,rec);/*读条记录*/
				/*文件指针回退dCount个长度,写入读进的记录,即删除了以上的dCount条记录*/
				fseek(opened_fp[fpi],-dbf_name->dhRecLen*(dCount+1),1);
				WriteRec(opened_fp[fpi],dbf_name,rec);				
				/*文件指针再往前指,以读下条记录*/
				fseek(opened_fp[fpi],dbf_name->dhRecLen*dCount,1);
				if (eof(dbf_name->dhHandle))
				{
					/*文件长度减去dCount个记录长度*/
					break;
				}
				Delete = 0;
				continue;
			}
			/*刚才读进那条记录符合删除条件,显示该记录则继续读下条记录*/
			if (dCount > 0)
			{
				ShowRec(opened_fp[fpi],dbf_name,recIn);
				dbf_name->dhRecNO = i;
			}
			else
				fseek(opened_fp[fpi],dbf_name->dhRecLen,1);
			Delete = FALSE;
		}/*end of for (i=0; i<dbf_name->dhRecCount;i++)*/
	}
	/*free(tempRec);
	free(recIn);
	tempRec = NULL;
	recIn = NULL;*/
	if (dCount <= 0)
	{
		puts("	没有符合删除条件的记录");
		return;
	}
	/*更改文件长度*/
	fflush(opened_fp[fpi]);
	dbf_name->dhRecCount -= dCount;
	chsize(dbf_name->dhHandle, (filelength(dbf_name->dhHandle)-dCount*dbf_name->dhRecLen));
	printf("	DELETE %d records!!!\n",dCount);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -