📄 main.c
字号:
/*
* 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 + -