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

📄 main.c

📁 纯C语言写的小型通用数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
* Copyright (c) 2006,华中科技大学Dian团队
* All rights reserved.
* 
* 文件名称:LiuDataBase
* 摘    要:模拟交互式的SOL的基本功能:动态建表,组合查询,删除,添加,更新
*           支持的数据类型为:char(字符型) int(整数型) double(浮点型) string(字符串型)
* 
* 当前版本:清级(后继版本依次为明级,元级....)
* 作    者:刘焱
* 完成日期:
* 友情下载:http://www.codefans.net
* 修改日期:
* 修改内容:
* 
*/



/***************************************************************************************************************/




/*头文件部分*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>





/***************************************************************************************************************/






/*宏定义部分*/


#define TABLE_LENTH 20   //定义表的长度
#define MAX_DATA_LEN 20  //定义最大字段数
#define MAX_NAME_LENTH 20  //定义字段名的最大长度
#define MAX_LEN_FILE_NANE 127  //定义文件名的最大长度
#define MAX_STRING_LENGTH 127 //定义字符串的最大长度
#define OK 1    //操作成功
#define ERROR 0   //操作失败
#define INITSTATUS -1 //初始状态
#define  SUPER_MARKET_MODEL 0//超市模式
#define  OFFICE_MODEL 1//办公模式


int  nModel=SUPER_MARKET_MODEL;//唯一的全局变量,记录系统模式









/***************************************************************************************************************/


/*数据结构定义部分*/



//定义元素类型
union Elemtype
{
	char CHAR;   //字符型
	char STRINR[MAX_STRING_LENGTH];  //字符串型
	int INT;//整数型
	double DOUBLE;//浮点型

};




//定义元素节点类型
struct Node
{
	union Elemtype arr[MAX_DATA_LEN];
	struct Node *next;

};




//字段基本信息结构体
struct Data
{
	char strName[MAX_NAME_LENTH];  //字段名
	int nLen;  //字段长度
	char cType; //字段类型 
};





//记录字段基本信息的节点结构体
struct DataNode
{
	struct Data data;//字段基本信息结构体
	struct DataNode *pNext;//指针

};





//记录所有字段信息的表结构体
struct Table
{
	int nLen;//表的长度
	struct Data Head[MAX_NAME_LENTH];//记录字段全部信息的数组


	int nCount;//记录数据容量
};




//定义文件结构
struct File
{
	struct Table *pTable;//表头指针
	struct Node *pHead;//数据区指针
	int    nCount;//数据区容量
};





/***************************************************************************************************************/




/*函数定义部分*/



void SubMenu(struct File *file);
void AddData(struct File *file);
void Read(struct File  *file,char *strFileName);
void MyUpdateData(struct Node *pCur,struct File *file);
void Update( struct File *file);
void  ShowTable(struct Table *pTable);
void ShowData(  union Elemtype  *arr ,struct File *file );
void AddData(struct File *file);
void Add(struct File *file);
void CheckChar(  struct File *file , int *bIsOK , int nIndex  );
void CheckDouble(  struct File *file , int *bIsOK, int nIndex   );
void CheckInt(  struct File *file , int *bIsOK, int nIndex  );
void CheckString(  struct File *file , int *bIsOK , int nIndex  );
void CreateTable(struct Table *pTable);
void Delete(struct File *file);
void DelteFile(  struct File *file );
void Driver();
void Find(struct File *file);
void GetChar(char *pChar);
void GetString(char *str);
int GetStrName(char *str);
void Help();
void InitFile(struct File *file);
void MainMenu();
void MyUpdateData(struct Node *pCur,struct File *file);
void New(struct File *file);
void Open(struct File *file);
void Read(struct File  *file,char *strFileName);
void ReadData(struct File *file,char *strFileName);
void ReadTable(struct File *file,char *strFileName);
void Save(struct File  file,char *strFileName);
void SaveData(struct File  file,char *strFileName);
void SaveTable(struct Table *pTable,char *strFileName);
void ShowData(  union Elemtype  *arr ,struct File *file );
void  ShowTable(struct Table *pTable);
void SubMenu(struct File *file);


/*
 *  函数功能:获取字段类型,并处理异常

 *  输入参数:字段名指针str
 *  输出参数:字段名指针str
 *  返 回 值:无   
 */
void GetString(char *str)
{
	

	while(1)
	{
	
		gets(str);
	
		if(strlen(str))
		{
			break;
		}
		printf("输入不可为空\n请在输入一遍\n");

	}

}






/*
 *  函数功能:初始化文件,为表头,数据区分配空间,其余各项置零

 *  输入参数:文件指针
 *  输出参数:无
 *  返 回 值:无
 */
void InitFile(struct File *file)
{
	struct Node *p;
	p=(  struct Node * )malloc(  sizeof(struct Node )  );
	p->next=NULL;
	file->pHead=p;
	file->nCount=0;
	file->pTable=(  struct Table *  )malloc(  sizeof(  struct Table  )  );
	file->pTable->nCount=0;
	file->pTable->nLen=0;
}



/*
 *  函数功能:获取字段名,并处理异常

 *  输入参数:字段名指针str
 *  输出参数:字段名指针str
 *  返 回 值:状态 1 表示输入成功并继续字段的输入  状态 0  退出字段输入   
 */


int GetStrName(char *str)
{
	char strChoice[20];
	char ch;
	

	while(1)
	{


		/*吸收回车符*/
	//    ch=getchar();
		
		/*截取字符段*/
		gets(str);


	  
		if(  strlen( str ) )
		{

		/*输入字符串非空则返回*/

			return OK;
		}
/*		else if( ERROR==IsRight(str) )
		{
			printf("%s已存在,请重命名:\n ");
			continue ;

		}*/
		else 
		{

			/*
			输入字符串为空则人机交互,
			判断是误操作还是退出建库
			*/
			printf("退出建库?(Y/any key)");
			gets(strChoice);
			if('Y'==strChoice[0])
			{
				return ERROR;
			}
			else 
			{
				printf("请输入数据名:\n");
				continue;

			}
		}
		

	}

}


int IsRight( struct Table *pTable, char *str )
{
	int i;
	int nCount;
//	printf("~~~~~%d ~~~~",pTable->nLen);
	for( i=0 ,nCount=MAX_DATA_LEN; i < nCount ; i++ )
	{
		if( 0 == strcmp( pTable->Head[i].strName, str))
		{
			return ERROR;
		}
	}
	return OK;
}





/*
 *  函数功能:建表并加载信息

 *  输入参数:表指针
 *  输出参数:记录所有字段信息的Table指针
 *  返 回 值:无
 */

void CreateTable(struct Table *pTable)
{
	int len=0;
	char string[20];
	char strChoice[20];
	struct Data data;





	printf("请输入数据名:\n");
	gets(data.strName);


//	puts(data.strName);



	if(!strlen(data.strName))
	{
			printf("退出建库?(Y/any key)");
			gets(strChoice);
			if('Y'==strChoice[0])
			{
				pTable->nLen=0;
				return ;
			}
			else
			{
				printf("请输入数据名:\n");
				gets(data.strName);




	puts(data.strName);




			}

	}

           printf("请输入数据类型:\n");
            while(1)
			{
				 GetString(string);
			//	gets(string);
				 if(  string[0]=='i' || string[0]=='s' ||string[0]=='c' || string[0]=='d'  )
				 {
					 break;
				 }
				 else
				 {
					 printf("对不起,本软件支持的数据类型为:\n char(字符型) int(整数型) double(浮点型) string(字符串型)\n 不支持该数据类型,请重新输入:\n");
					 continue;
				 }

			}
		   
	     	data.cType=string[0];
			switch (string[0])
			{
			    case 's':
					 printf("请输入数据长度:\n");
		             scanf("%d",&data.nLen);


					 getchar();


					 break;
				case 'c':
					data.nLen=1;
					break;
				case 'i':
					data.nLen=2;
					break;
				case 'd':
					data.nLen=4;
					break;

			}
		   
	       
		    pTable->Head[len++]=data;



	
	
	while(len<TABLE_LENTH)
	{


		printf("请输入数据名:\n");

		if(  ERROR == GetStrName(data.strName))
		{
			puts(data.strName);
		   pTable->nLen=len;
		   	printf("成功建立表头!\n");
	

			return;

		}
		else if( ERROR ==IsRight( pTable , data.strName ) ) 
		{
			printf("%s已存在,请重命名\n  ",data.strName );
			continue; 
		}
		else 
		{
		    printf("请输入数据类型:\n");
            while(1)
			{
				 GetString(string);
				 if(  string[0]=='i' || string[0]=='s' ||string[0]=='c' || string[0]=='d'  )
				 {
					 break;
				 }
				 else
				 {
					 printf("不支持该数据类型,请重新输入:\n");
					 continue;
				 }

			}
		   
	     	data.cType=string[0];
			switch (string[0])
			{
			    case 's':
					 printf("请输入数据长度:\n");
		             scanf("%d",&data.nLen);
					 break;
				case 'c':
					data.nLen=1;
					break;
				case 'i':
					data.nLen=2;
					break;
				case 'd':
					data.nLen=4;
					break;

			}
		   
	       
		    pTable->Head[len++]=data;
		}
	
	}

	pTable->nLen=len;





}






/*
 *  函数功能:打开文件,获取表头

 *  输入参数:表指针,文件名
 *  输出参数:记录所有字段信息的Table指针
 *  返 回 值:无
 */
void ReadTable(struct File *file,char *strFileName)
{
		FILE *pFILE;
		struct Table *pTable=file->pTable;





	if(   ERROR== (pFILE=fopen(strFileName,"rb+")))
	{
		printf("文件%s无法打开!\n",strFileName);
		return;
	}
	else
	{
		fread(pTable, sizeof( struct Table),1,pFILE);
		file->nCount=file->pTable->nCount;
		fclose(pFILE);


		printf("\n成功解读文件%s的表头!\n",strFileName);

	}

}













/*
 *  函数功能:将表存入文件

 *  输入参数:表指针,文件名指针
 *  输出参数:记录所有字段信息的Table指针以及文件名
 *  返 回 值:无
 */

void SaveTable(struct Table *pTable,char *strFileName)
{

	FILE *pFILE;




    	if(!pTable)
	{
		printf("表指针为空,无法保存!\n");
		return;
	}



	if(   ERROR== (   pFILE =  fopen(  strFileName  ,"wb+")  )  )
	{
		printf("文件%s无法打开!\n",strFileName);
		return;
	}
	else
	{
		fwrite(  pTable,   sizeof(  struct Table  ),1,pFILE);
		fclose(pFILE);


		printf("成功在文件%s中保存表头!\n",strFileName);

	}

}


/*
 *  函数功能:显示文件表头

 *  输入参数:表指针
 *  输出参数:无
 *  返 回 值:无
 */
void  ShowTable(struct Table *pTable)
{
	int i;



	if(!pTable)
	{
		printf("表指针为空,无法解读!\n");
		return;
	}
	printf("\n\n本数据文件最大字段数为:%d\n当前字段数为:%d\n各字段信息如下:\n",TABLE_LENTH ,pTable->nLen);
	printf("字段名\t\t字段长度\t\t数据类型\n");
	

	for(i=0;i<pTable->nLen;i++)
	{
		printf("%s\t\t%d\t\t\t%c\n",pTable->Head[i].strName,pTable->Head[i].nLen,pTable->Head[i].cType);
	

	}
	printf("\n\n");


}



/*
 *  函数功能:在文件的数据区追加数据
 *  输入参数:表指针pTable,文件名指针strFileName
 *  输出参数:无
 *  返 回 值:无
 */
void SaveData(struct File  file,char *strFileName)
{
	FILE *pFILE;
	struct Table *pTable=file.pTable;

	struct Node *pCur=file.pHead->next;
	int nCount;
	
	




    
	if(!pTable)
	{
		printf("表指针为空,无法解读文件结构!\n");
		return;

	}
	else
	{
		if(   ERROR == ( pFILE = fopen(strFileName,"ab" )  )   )
		{
			printf("文件%s无法打开!\n",strFileName);
			return;
		}
		else
		{
			if(!pCur||!pCur->next)
			{
				printf("文件为空,请确认数据已加载!\n");
				return;
			}
            
			for(  nCount=0;  nCount<file.nCount   ;nCount++,pCur=pCur->next)
			{
			//	printf("已存储第%d个数据项%c\n",nCount,pCur->arr[0].CHAR);
			
				fwrite(  pCur->arr,  sizeof(  union Elemtype  )*MAX_DATA_LEN  ,  1  ,  pFILE  );
				
			}
			
            printf("已成功将%d个记录保存在文件%s\n",nCount,strFileName);
			fclose(pFILE);

		}

	}



	

}




/*
 *  函数功能:显示元组内容

 *  输入参数:元组指针arr,文件指针file
 *  输出参数:无
 *  返 回 值:无
 */
void ShowData(  union Elemtype  *arr ,struct File *file )
{
	struct Table table=*(file->pTable);//获取文件表头
	int nLen=file->pTable->nLen;//获取文件字段总数
	int i;
	char type;


	/*按照表头信息逐个显示数据*/
	for(  i=0 ;  i< nLen ; i++ )
	{


		type=table.Head[i].cType;

		/*输出字段名*/
		printf("\n%s:",table.Head[i].strName);



			switch (type)
			{
		                     case 'c':
								 printf("\t%c",arr[i].CHAR);
						
								 break;
							 case 's':
								 printf("\t%s",arr[i].STRINR);
						
								  break;
							 case 'd':
								 printf("\t%.2lf",arr[i].DOUBLE);
						
								  break;
							case 'i':
								printf("\t%d",arr[i].INT);
							
								  break;
								 


							 default:
								 printf("无法识别的数据类型!\n");




			}


	}
	puts("");






}



/*
 *  函数功能:读取文件数据区

 *  输入参数:表指针pTable,文件名指针strFileName
 *  输出参数:无
 *  返 回 值:无
 */
void ReadData(struct File *file,char *strFileName)
{
	
		FILE *pFILE;
	
		char type;
		struct Table t;
		struct Table *pTable=file->pTable;
		struct Node *pCur;
		struct Node data;
		int i,j;
		
		

 


    
	if(!pTable)
	{
		printf("表指针为空,无法解读文件结构!\n");
		return;

	}
	
	
		if(   ERROR == ( pFILE = fopen(strFileName,"rb" )  )   )
		{
			printf("文件%s无法打开!\n",strFileName);
			return;
		}
/*		if(  NULL ==file->pHead->next)
		{
			printf("文件数据区为空!\n");
			return;

		}
		
*/			
			

 //        printf("正在读取文件%s的数据区\n\n",strFileName);
			fread(&t,sizeof(struct Table),1,pFILE);


			for(  i=0  ;   i<file->pTable->nCount    ;  i++   )
			{
				


⌨️ 快捷键说明

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