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

📄 dbms.cpp

📁 这是一个基于dos的dbms
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//:DBMS.cpp
// 		DBMS v1.1 数据库系统实现源程序
//                作者:余康华 2002.2.7
//   		  版权所有 (C) 2002 余康华
//文件大小:DBMS.CPP: 960行  29466 Bytes
//          DBMS.EXE:  66462 Bytes
//请在此处加入您的版权信息:
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <myfunc.h>
#include <ctype.h>
#include <io.h>      //For access()
#include <process.h> //For system()
#include <type.h>
#include <menu.h>
#include <mouse.h>
#include "dbms.h"
///Macro definations//////////////////////////////////////////
//#define  PSat(x,y,s) gotoxy(x,y);cputs(s)
#define  ClrLine(x,y) gotoxy(x,y);clreol()
///Globla Variables///////////////////////////////////////////
TDBF DBF[10]; // Max opened DBFfile at one time
int  CurWork=0;
int  LastWork=0;
char cmdstr[81];
struct time Time;
int drawflag=1;
 int ListLine=5;
/// Function prototypes///////////////////////////////////////
void Quit();
void Help();
void Dir();
////////////////////////////////////////////////////////////
int IsAllSpace(char *s)
 {  while(*s) if((*s!=' ')&&(*s!='\n')) return 0;
	 return 1;
 }
void ReadFile(char *buf,int sz,FILE *fp,char stop='\n')
 {
  char ch;
  ch=fgetc(fp);
  while((ch!=stop)&&(!feof(fp))&&sz)
	{ *buf++=ch; ch=fgetc(fp); }
  *buf=0;
 }
////////////////////////////////////////////////////////////
// x,y: 起始点坐标
//num:  "点"数
//hor: 是否为横(默认值)
void Line(int x,int y,int num,int hor=1)
 {
  gotoxy(x,y);
  if(hor)for(int i=0;i<num;i++) { gotoxy(x+i,y);putch(196);}
	 else for(int j=0;j<num;j++) { gotoxy(x,y+j);putch(179);}
 }
////////////////////////////////////////////////////////////
//在字符方式下 输入一个字符串。
void  Input(int x,int y,char *str)
 { char s[80];
	s[0]=80;
	gotoxy(x,y);
	cgets(s);
	if(s[1]==0||s[2]==27) strcpy(str,"");
	else strcpy(str,s+2);
 }
////////////////////////////////////////////////////////////
//在字符方式下 输入一个数值。
void  InputInt(int x,int y,int *i)
 {
  char s[12];
  s[0]=10;
  gotoxy(x,y);
  cgets(s);
  if(s[1]==0||s[2]==27) *i=0;
	else  *i=atoi(s+2);
 }
////////////////////////////////////////////////////////////
//TDBF类的构造函数据
TDBF::TDBF(char *fn)
 {  strcpy(FileName,fn);
	CurRec=Header.Next=0;
	Header.Prev=0;
	fp=NULL;
	RecCount=FieldCount=0;
	State=0;
 }
////////////////////////////////////////////////////////////
//添加下条记录
void TDBF::Add(int pos)
 {
  do{
	MenuDraw();
	if(DBF[CurWork].fp==NULL)
	 { Prompt("当前工作区间未打开文件");return;}
	clrscr();
	gotoxy(1,1);
	gettime(&Time);
	ClrLine(1,1);
	cprintf(" YKH 数据库管理统系-[当前工作区间%c-->%s]",CurWork+'A',DBF[CurWork].FileName);
	gotoxy(66,1);
	cprintf("[%2d:%2d:%2d]",Time.ti_hour,Time.ti_min,Time.ti_sec);
	textcolor(BLUE);
	Line(1,4,80);
	textcolor(YELLOW);
	PSat(30,5,"添加记录");
	Line(1,6,80);
	TRecord *old=0;
	if(pos!=-1&&pos!=0&&pos<=RecCount) // Default position ---before Current record
	  { old=CurRec;Goto(pos);}
	  PSat(1,8,"记录号 #");
	  gotoxy(1,9);
	  if(RecCount==0)CurRec->NO=1;
	  cprintf("%-4d",CurRec->NO);
	  int len=10;
	  for(int i=0;i<FieldCount;i++)
	  {
	  PSat(len,8,FieldName[i]);
	  len+=FieldWidth[i]+1;
	  }
	  TRecord *T=new TRecord;
	  T->Next=0;
	  for(i=0;i<FieldCount;i++)
	  { T->Values[i]=new char[FieldWidth[i]+1]; //为一个记录分配空间
		 if(T->Values[i]==0) { PSat(1,25,"没有足够的内存");getch();return;}
	  }
	 len=10;
	 textbackground(BLUE);
	 for(i=0;i<FieldCount;i++){
		gotoxy(len,9);
		for(int j=0;j<FieldWidth[i];j++) putch(' ');
		len+=FieldWidth[i]+1;}
	 len=10;
	 for(i=0;i<FieldCount;i++){ Input(len,9,T->Values[i]);
		len+=FieldWidth[i]+1;}
	 if(CurRec==0){
		RecCount=1;
		Header.Next=T;
		CurRec=T;
		T->NO=1;
		T->Next=T->Prev=0;}
	 else {
		T->Next=CurRec->Next;
		CurRec->Next=T;
		T->Prev=CurRec;
		T->NO=CurRec->NO+1;
		while(T->Next!=0) { T->Next->NO++; T=T->Next;}
		RecCount++;}
	 textbackground(BLACK);
	 Modified=1;
	 if(old!=0) CurRec=old; // to the old position if not use default pos=-1
	char c=Prompt("成功插入记录!是否继续[Y/N]<Y>");
	if(c=='Y'||c=='y'||c=='\n'||c=='\r') {CurRec=CurRec->Next;continue;}
	else break;
  }while(1);
  }
////////////////////////////////////////////////////////////
void TDBF::ListField()
{
  int len=12;
  textcolor(RED);
  for(int i=0;i<FieldCount;i++)
	{ PSat(len,4,FieldName[i]);
	  len+=FieldWidth[i]+1;
	}
  PSat(2,4,"记录号#");
  textcolor(YELLOW);
}
////////////////////////////////////////////////////////////
void TDBF::List(word start,word end)
 {
  if(DBF[CurWork].FieldCount<1)
	{ gotoxy(30,4);
	  cputs("当前工作区间没有字段");
	  return;
	}
  TRecord *T=Header.Next;
  while(T!=0&&T->NO!=start) T=T->Next;
  if(T==0) return;
  int page=1;
  int len=12;
  int i;
  ListField();
  if(end>RecCount) end=RecCount;
  while((T->NO-1!=end)&&(T!=0))
	{ 	if(page%21==0) {
		 ListLine=5;
		 PSat(1,25,"敲任意键继续...");getch();
		 ClrLine(1,1);
		 gettime(&Time);
		 ClrLine(1,1);
		 cprintf(" YKH 数据库管理统系-[当前工作区间%c-->%s]",CurWork+'A',DBF[CurWork].FileName);
		 gotoxy(69,1);
		 cprintf("[%2d:%2d:%2d]",Time.ti_hour,Time.ti_min,Time.ti_sec);
		 textcolor(BLUE);  Line(1,2,80);
		 textcolor(RED);
		 ListField();
		}
		len=12;
		textcolor(CYAN);
		gotoxy(3,ListLine);
		cprintf("%-6d",T->NO);
		page++;
		textcolor(YELLOW);
		Line(1,4,80);
		for( i=0;i<FieldCount;i++){
		  PSat(len,ListLine,T->Values[i]);
		  len+=FieldWidth[i]+1;
		}
		if(T->Flag=='D'){ PSat(2,ListLine,"*"); }       /// if it have flag
		if(T->NO==CurRec->NO){ PSat(1,ListLine,">");}
	  ListLine++;
	  len=12;
	  T=T->Next;
	 }
 }
////////////////////////////////////////////////////////////
void  TDBF::Release()
{
 TRecord *T=Header.Next;
 while(T->Next!=0) T=T->Next;
 TRecord *r=T=T->Prev;
 while(T!=Header.Next) {delete T->Next;T=r;r=T->Prev; }
 delete Header.Next;
 Modified=0; Header.Next=CurRec=0; RecCount=0; State=0;
 }
////////////////////////////////////////////
void  TDBF::Save()
{
 if(!Modified) return;
 if(fp==NULL) {  Prompt("还没有打开任何文件!");return;}
 fseek(fp,0,0);
 putw(0x5432,fp); //add into a file flag
 putw(FieldCount,fp);
 putw(RecCount,fp);
 char qq[20];
 for(int i=0;i<FieldCount;i++)
  { itoa(FieldWidth[i],qq,10);
	 fputs(FieldName[i],fp);
	 fputc('\n',fp);
	 fputs(qq,fp);
	 fputc('\n',fp);
	}
 TRecord *T=Header.Next;
 for(i=0;i<RecCount;i++)
  {
	 fputc(T->Flag,fp);
	 for(int j=0;j<FieldCount;j++)
	 { fputs(T->Values[j],fp);
		fputc('\n',fp);
	  }
	 T=T->Next;
  }
 Modified=0;
 ClrLine(1,25);
 Prompt("成功保存文件!");
 ClrLine(1,25);
}
///////////////////////////////////////////////////////
void  TDBF::Modify(int no)
 {
  TRecord *old;
	 if(DBF[CurWork].FieldCount<1)
	{ gotoxy(30,4);
	  cputs("当前工作区间没有字段");
	  return;
	}
  if(no!=0) { old=CurRec;Goto(no);}
  Modified=1; //will modify
  int len=12;
  clrscr();
  gotoxy(1,1);
  gettime(&Time);
  ClrLine(1,1);
  cprintf(" YKH 数据库管理统系-[当前工作区间%c-->%s]",CurWork+'A',DBF[CurWork].FileName);
  gotoxy(69,1);
  cprintf("[%2d:%2d:%2d]",Time.ti_hour,Time.ti_min,Time.ti_sec);
  textcolor(BLUE);  Line(1,2,80);
  ListField();
  len=12;
  gotoxy(3,5);
  textcolor(CYAN);
  cprintf("%-6d",CurRec->NO);
  for(int i=0;i<FieldCount;i++)
  { PSat(len,5,CurRec->Values[i]);
	 len+=FieldWidth[i]+1;
  }
  cprintf("      <---记录的旧值");
  gotoxy(len,6);
  cprintf("  <---新值");
  len=12;
  if(CurRec->Flag=='D'){ PSat(2,5,"*"); }       /// if it have flag
  if(CurRec->NO==old->NO){ PSat(1,5,">");}
  textbackground(BLUE);
  for(i=0;i<FieldCount;i++)
  { gotoxy(len,6);
	 for(int j=0;j<FieldWidth[i];j++)putch(' '); //draw a lignt bar
	 len+=FieldWidth[i]+1;
  }
  len=12;
  textcolor(YELLOW);
  for(i=0;i<FieldCount;i++)
	{ Input(len,6,CurRec->Values[i]);
	  len+=FieldWidth[i]+1;
	}
  textbackground(BLACK);
  PSat(1,25,"成功修改记录!");
  getch();
  ClrLine(1,25);
 if(no!=0) CurRec=old;
 Modified=1;
 }
///////////////////////////////////////////////////////
void  TDBF::Load(char *fn)
{
 FILE *t;
 char s[80];
 if(fn==NULL)
 {
  ShowCursor();
  ClrLine(1,25);
  PSat(1,25,"输入文件名:");
  s[0]=70;
  cgets(s);
  if(s[1]==0||s[2]==27) return;
  if(fp!=NULL&&Modified){   //File No save question if save
	 ClrLine(1,25);
	 PSat(1,25,"文件被修改,是否保存?[Y/N]<Y>");
	 char c=getch();
	 if(c=='Y'||c=='y'||c=='\r'||c=='\n') Save();
	 Release();        //Relase the old record link
	 }
 }
 else strcpy(s+2,fn);
 strcat(s,".YDB");
 strcpy(FileName,s+2);
 t=fopen(FileName,"r+");
 if(!t)
 { strcpy(FileName,"Untitled.YDB");
 ClrLine(1,25);PSat(1,25,"文件未找到!");getch();return;}
 unsigned w;
 fseek(fp,0,0);
 w=getw(t);
 if(w!=0x5432){ Prompt("文件的格式不是正确!");ClrLine(1,25);cputs("命令:");return;  }
 fp=t;
 FieldCount=getw(fp);
 RecCount=getw(fp);
 char qq[70];
 for(int i=0;i<FieldCount;i++)
  { ReadFile(FieldName[i],11,fp);
	 ReadFile(qq,FieldWidth[i]+1,fp);
	 FieldWidth[i]=atoi(qq);
  }
  int num=1;
 for(i=0;i<RecCount;i++)
  { TRecord *T=new TRecord;
	 if(!T) { ClrLine(1,25);PSat(1,25,"没有足够的内存"); getch(); return;}
	 T->Flag=getc(fp);
	 for(int j=0;j<FieldCount;j++)
	  {  T->Values[j]=new char[FieldWidth[j]+1];
			if(!T->Values[j]){ ClrLine(1,25);PSat(1,25,"没有足够的内存");getch();return;}
			ReadFile(T->Values[j],FieldWidth[j]+1,fp);
		}
	 if(CurRec==0){//最先没有记录
			CurRec=T;T->NO=1;CurRec->NO=1;Header.Next=T;T->Prev=T->Next=0;}
	 else{
		T->Next=CurRec->Next;     //插入一条记录
		T->Prev=CurRec;
		CurRec->Next=T;
		CurRec=T;
		T->NO=++num;}
  }
  Modified=0;
  CurRec=Header.Next;
  CurRec->NO=1;
  State=1;
  Prompt("成功加载文件");
  ClrLine(1,25);
 }
////////////////////////////////////////////////////////////
void  TDBF::Create(char *fn)
{
  char s[50];
  if(fn==NULL)
	{ if(Modified){
	  char c;
	  PSat(1,25,"文件未保存,是否保存?[Y/N/C取消]<Y>");
	  c=getch();
	  if(c=='y'||c=='Y'||c=='\n'||c=='\r') Save();
	  if(c=='c'||c=='C') return;
	  Release();
	 }
	if(fp!=NULL) Close();
	PSat(1,25,"输入文件名:");
	s[0]=13;
	cgets(s);
	if(s[1]==0||s[2]==27) return;
	strcpy(FileName,s+2);
  }
 else strcpy(FileName,fn);
 strcat(FileName,".YDB");
 if(access(FileName,0)==0)
  {
	ClrLine(1,25);
	PSat(1,25,"文件已存在,是否覆盖<Y/N/C取消]<Y>?");
	char c=getch();
	if(c=='n'||c=='N'||c=='\n'||c=='\r')
	  {
		 PSat(1,25,"输入文件名:");
		 Input(12,25,FileName);
		}
	else if(c=='c'||c=='C') { strcpy(FileName,"Untitled.YDB");return;}
	}
 ClrLine(1,25);
 gotoxy(1,25);
 cputs("输入字段个数:");
 s[0]=10;
 cgets(s);
 if(s[1]==0||s[2]==27) return ;
 FieldCount=atoi(s+2) %MAXFIELD;
 fp=fopen(FileName,"w+");
 if(!fp)
	{PSat(1,25,"不能建立文件!");
	 getch();
	 strcpy(FileName,"Untitled.YDB");
	 return;
	}
 clrscr();
 gettime(&Time);
 ClrLine(1,1);
 gettime(&Time);
 ClrLine(1,1);
 cprintf(" YKH 数据库管理统系-[当前工作区间%c-->%s]",CurWork+'A',DBF[CurWork].FileName);
 gotoxy(69,1);
 cprintf("[%2d:%2d:%2d]",Time.ti_hour,Time.ti_min,Time.ti_sec);
 textcolor(BLUE);  Line(1,2,80);
 textcolor(RED);
 PSat(20,5,"字段名                 字段长度");
 Line(1,6,79);
 textcolor(YELLOW);
 textbackground(BLUE);
 for(int n=0;n<FieldCount;n++)
  { PSat(20,7+2*n,"                ");
	 PSat(43,7+2*n,"        ");
  }
int allwidth=10;
for( n=0;n<FieldCount;n++)
  { FNAG: Input(20,7+2*n,FieldName[n]);
		if(FieldName[n][0]==0){
		  textbackground(BLACK);
		  PSat(1,25,"请输入一个字段名");
		  textbackground(BLUE);
		  goto FNAG;}
	 FWAG: InputInt(43,7+2*n,&FieldWidth[n]);
		if(FieldWidth[n]<1){
		  textbackground(BLACK);
		  PSat(1,25,"请输入一个正整数");
		  textbackground(BLUE);
		  goto FWAG;}
	 allwidth+=FieldWidth[n];
  }
 if(allwidth>80){ // total the widths exceed 80 characters
	int est=0;    // if that, choose a lengthest field and decreae it
	for( n=1;n<FieldCount;n++)
	if(FieldWidth[est]<FieldWidth[n]) est=n;
	FieldWidth[est]-=(80-allwidth);
	}
 textbackground(BLACK);
 PSat(1,25,"成功建立文件,现在输入记录吗?[Y/N]<Y>");
 char ch=getch();
 if(ch=='y'||ch=='Y'||ch=='\n'||ch=='\r') Add();
 Modified=1;
 State=1;

 }
////////////////////////////////////////////////////////////
void  TDBF::Close()
 {
  if(fp==NULL) return;
  if(Modified&&fp!=NULL)

⌨️ 快捷键说明

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