/************************************
名 称:同学录
作 者:freewind
版 本:v1.0
时 间:2006-08
Email:freewind22@163.com
*************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define CLS system("cls")
#define LEN sizeof(Student)
#define NUM 4
#define NAME 6
#define OICQ 10
#define TEL 12
#define ADDRESS 36
#define TRUE 1
#define FALSE 0
#define PAGENUM 10
#define X 12
#define Y 12
#define Z 20
typedef struct student
{
char Num[NUM+1];
char Name[NAME+1];
char Oicq[OICQ+1];
char Tel[TEL+1];
char Address[ADDRESS+1];
struct student *Next;
}Student;
Student *Head=0;
Student *Last=0;
int Count=0;
char School[X+1],Yuan[Y+1],Class[Z+1];
char Title[81];
/*************************************** GetChar *********************************/
char GetChar(const char * str)
{
char ch;
int i,len=strlen(str);
while(TRUE)
{
ch=getch();
for(i=0;i<len;i++)
if( ch==str[i] ) return ch;
}
}
/*************************************** Insert *********************************/
void Insert(Student * p)
{
Student *h,*q;
for(h=Head; h && strcmp(h->Num,p->Num)<0; q=h,h=h->Next);
if( h==Head )
{
Head=p;
p->Next=h;
}else
{
p->Next=h;
q->Next=p;
}
}
/************************************* Delete ***********************************/
void Delete( Student *p )
{
Student *q;
if ( p==Head )
{
Head=Head->Next;
}else
{
for( q=Head; q && q->Next !=p; q=q->Next )
;
q->Next=p->Next;
}
free(p);
}
/************************************* Search ***********************************/
Student * Search( char * str, int mode )
{
Student *p=Head;
switch(mode)
{
case NUM:
while( p )
{
if( !strcmp(p->Num,str) ) break;
p=p->Next;
}
break;
case NAME:
while( p )
{
if( !strcmp(p->Name,str) ) break;
p=p->Next;
}
break;
case OICQ:
while( p )
{
if( !strcmp(p->Oicq,str) ) break;
p=p->Next;
}
break;
}
return p;
}
/************************************* CheckData *********************************/
void CheckData( Student *p, char * ErrMsg )
{
if( strlen(p->Num) > NUM ) strcat(ErrMsg,"〖学号〗");
if( strlen(p->Name) > NAME ) strcat(ErrMsg,"〖姓名〗");
if( strlen(p->Oicq) > OICQ ) strcat(ErrMsg,"〖QICQ〗");
if( strlen(p->Tel) > TEL ) strcat(ErrMsg,"〖电话〗");
if( strlen(p->Address) > ADDRESS ) strcat(ErrMsg,"〖地址〗");
}
/************************************* User Interface ****************************/
void UI()
{ /*②③④⒈⒉⒊⒋⒌⒍╔ ╗╚ ╝╠ ╣╦ ╩ ╬║═╒ ╕╘ ╛╞ ╡┬ ┴*/
int i,len=strlen(Title);
CLS;
printf(" ╔═════════════════════════════════════╗/n");
printf(" ║ ║/n");
printf(" ║");
for(i=0;i<(74-len)/2;i++)
printf(" ");
printf("%s",Title);
for(i=i+len+1;i<74;i++)
printf(" ");
printf(" ║/n");
/*printf(" ║ ☆★☆ XX大学YY学院『2005计算机与信息管理』同学录 ☆★☆ ║/n");*/
printf(" ║ ║/n");
printf(" ╠═════════════════════════════════════╣/n");
printf(" ║ ┌──────┐ ┌───────┐ ┌──────┐ ┌──────┐ ║/n");
printf(" ║ │〖 1.管理 〗│ │ 〖 2.查询 〗 │ │〖 3.设置 〗│ │〖 4.帮助 〗│ ║/n");
printf(" ║ ├──────┤ ├───────┤ ├──────┤ ├──────┤ ║/n");
printf(" ║ │ ⒈档案输入 │ │ ⒈按学号查询 │ │ ⒈系统设置 │ │ ⒈关于... │ ║/n");
printf(" ║ │ ⒉删除档案 │ │ ⒉按姓名查询 │ └──────┘ │ ⒉使用说明 │ ║/n");
printf(" ║ │ ⒊修改档案 │ │ ⒊按OICQ查询 │ └──────┘ ║/n");
printf(" ║ │ ⒋显示全部 │ └───────┘ ║/n");
printf(" ║ │ ⒌退出系统 │ ║/n");
printf(" ║ └──────┘ ║/n");
printf(" ║ ║/n");
printf(" ║ ║/n");
printf(" ║ ║/n");
printf(" ║ ║/n");
printf(" ║ ║/n");
printf(" ║ ║/n");
printf(" ║ ║/n");
printf(" ╚═════════════════════════════════════╝/n");
}
/************************************ InputRecord *******************************/
void InputRecord(Student *Record)
{
int Exit=FALSE;
char ErrMsg[50],ch;
Student *p=(Student *)malloc(LEN);
while( !Exit )
{
if ( !Record ) CLS;
ErrMsg[0]=0;
printf("┌─────────────────────────────────────┐/n");
printf("│ 〖 档案输入 〗 │/n");
printf("├─────────────────────────────────────┤/n");
printf("│ 输入格式:学号(%3d) 姓名(%3d) OICQ(%3d) 电话(%3d) 地址(%3d) │/n",NUM,NAME,OICQ,TEL,ADDRESS);
printf("│ │/n");
printf("│ 括号里的数字为每项可以输入的最大字符数.每输入一项后按回车结束. │/n");
printf("└─────────────────────────────────────┘/n");
scanf("%s%s%s%s%s", p->Num, p->Name, p->Oicq, p->Tel, p->Address);
CheckData( p, ErrMsg );
if( ErrMsg[0] )
{
printf("/n%s 数据输入错误!!",ErrMsg);
printf("/n是否继续输入[Y/N]?");
ch=GetChar("YyNn");
if (ch=='N' || ch=='n')
{
free( p );
Exit=TRUE;
}
continue;
}
if( !Record )
{
p->Next=0;
if( !Head )
Head=Last=p;
else
Insert( p );
Count++;
}
else
{
strcpy( Record->Num, p->Num );
strcpy( Record->Name, p->Name );
strcpy( Record->Oicq, p->Oicq );
strcpy( Record->Tel, p->Tel );
strcpy( Record->Address, p->Address );
free( p );
}
Exit=TRUE;
}
}
/************************************ DeleteRecord **********************************/
void DeleteRecord()
{
int Exit=FALSE,len;
char str[11],ch;
Student *p;
while( !Exit )
{
CLS;
printf("┌─────────────────────────────────────┐/n");
printf("│ 〖 删除档案 〗 │/n");
printf("├─────────────────────────────────────┤/n");
printf("│ 请输入要删除档案的学号或姓名或OICQ,系统将查找符合条件的记录... │/n");
printf("└─────────────────────────────────────┘/n");
scanf("%s",str);
len=strlen(str);
if( len<4 || len>10)
{
printf("/n/n数据输入错误.是否继续[Y/N]?");
ch=GetChar("YyNn");
if ( ch=='N' || ch=='n' )
Exit=TRUE;
continue;
}
p=Search(str,NUM);
if( !p ) p=Search(str,NAME);
if( !p ) p=Search(str,OICQ);
if( !p )
{
printf("/n/n未找到符合条件的记录.是否继续[Y/N]?");
ch=GetChar("YyNn");
if ( ch=='N' || ch=='n' )
Exit=TRUE;
continue;
}
printf("/n/n 已找到符合条件的记录 /n");
printf("┌──┬───┬─────┬──────┬──────────────────┐");
printf("│学号│ 姓名 │ OICQ │ 电话 │ 地址 │");
printf("├──┼───┼─────┼──────┼──────────────────┤");
printf("│%-4s│%-6s│%-10s│%-12s│%-36s│",p->Num,p->Name,p->Oicq,p->Tel,p->Address);
printf("└──┴───┴─────┴──────┴──────────────────┘");
printf("/n 是否删除[Y/N]?");
ch=GetChar("YyNn");
printf("/n/n");
if( ch=='Y' || ch=='y' )
{
Delete( p );
printf("记录已被删除!/n");
Count--;
}else
{
printf("操作取消!记录没删除!/n");
}
printf("/n按任意键返回系统....");
Exit=TRUE;
getch();
}
}
/************************************ ModifyRecord **********************************/
void ModifyRecord()
{
int Exit=FALSE,len;
char str[11],ch;
Student *p;
while( !Exit )
{
CLS;
printf("┌─────────────────────────────────────┐/n");
printf("│ 〖 修改档案 〗 │/n");
printf("├─────────────────────────────────────┤/n");
printf("│ 请输入要修改档案的学号或姓名或OICQ,系统将查找符合条件的记录... │/n");
printf("└─────────────────────────────────────┘/n");
scanf("%s",str);
len=strlen(str);
if( len<4 || len>10)
{
printf("/n/n数据输入错误.是否继续[Y/N]?");
ch=GetChar("YyNn");
if ( ch=='N' || ch=='n' )
Exit=TRUE;
continue;
}
p=Search(str,NUM);
if( !p ) p=Search(str,NAME);
if( !p ) p=Search(str,OICQ);
if( !p )
{
printf("/n/n未找到符合条件的记录.是否继续[Y/N]?");
ch=GetChar("YyNn");
if ( ch=='N' || ch=='n' )
Exit=TRUE;
continue;
}
printf("/n/n 已找到符合条件的记录 /n");
printf("┌──┬───┬─────┬──────┬──────────────────┐");
printf("│学号│ 姓名 │ OICQ │ 电话 │ 地址 │");
printf("├──┼───┼─────┼──────┼──────────────────┤");
printf("│%-4s│%-6s│%-10s│%-12s│%-36s│",p->Num,p->Name,p->Oicq,p->Tel,p->Address);
printf("└──┴───┴─────┴──────┴──────────────────┘");
printf("/n 是否修改[Y/N]?");
ch=GetChar("YyNn");
printf("/n");
if( ch=='Y' || ch=='y' )
{
InputRecord( p );
}else
{
printf("操作取消!记录没修改!/n");
}
printf("/n按任意键返回系统....");
Exit=TRUE;
getch();
}
}
/************************************ ListAll *************************************/
void ListAll()
{
/*┌ ┐└ ┘├ ┤┬ ┴ ┼ ─│*/
Student *p=Head;
int i=0,curpage=0;
int Exit=FALSE;
char ch=0;
while( !Exit )
{
CLS;
printf("┌──┬───┬─────┬──────┬──────────────────┐");
printf("│学号│ 姓名 │ OICQ │ 电话 │ 地址 │");
while(p && (i-curpage*PAGENUM)<PAGENUM && i<Count)
{
printf("├──┼───┼─────┼──────┼──────────────────┤");
printf("│%-4s│%-6s│%-10s│%-12s│%-36s│",p->Num,p->Name,p->Oicq,p->Tel,p->Address);
p=p->Next;
i++;
}
printf("└──┴───┴─────┴──────┴──────────────────┘");
printf(" 共 %d 条记录. 当前为第 %d - %d 条. 下一页:N 上一页:P 返回系统:E ", Count, curpage*PAGENUM+1,i);
getkey:
ch=GetChar("NnPpEe");
if(ch=='N' || ch=='n')
{
if (i>=Count) goto getkey;
else curpage++;
}
if(ch=='P' || ch=='p')
{
if(i-PAGENUM<=0) goto getkey;
else
{
curpage--;
p=Head;
for(i=0;i<curpage*PAGENUM;i++)
p=p->Next;
}
}
if(ch=='E' || ch=='e')
Exit=TRUE;
}
}
/************************************ SearchRecord *********************************/
void SearchRecord( int mode )
{
int Exit=FALSE,len;
char str[11],strmode[5],ch;
Student *p;
switch( mode )
{
case NUM:
strcpy( strmode,"学号" );
break;
case NAME:
strcpy( strmode,"姓名" );
break;
case OICQ:
strcpy( strmode,"OICQ" );
}
while( !Exit )
{
CLS;
printf("┌─────────────────────────────────────┐/n");
printf("│ 〖 按% 4s查询 〗 │/n",strmode);
printf("├─────────────────────────────────────┤/n");
printf("│ 请输入要查询档案的% 4s,系统将查找符合条件的记录... │/n",strmode);
printf("└─────────────────────────────────────┘/n");
scanf("%s",str);
len=strlen(str);
if( len<4 || len>10)
{
printf("/n/n数据输入错误.是否继续[Y/N]?");
ch=GetChar("YyNn");
if ( ch=='N' || ch=='n' )
Exit=TRUE;
continue;
}
p=Search( str, mode );
if( !p )
{
printf("/n/n未找到符合条件的记录.是否继续[Y/N]?");
ch=GetChar("YyNn");
if ( ch=='N' || ch=='n' )
Exit=TRUE;
continue;
}
printf("/n/n 已找到符合条件的记录 /n");
printf("┌──┬───┬─────┬──────┬──────────────────┐");
printf("│学号│ 姓名 │ OICQ │ 电话 │ 地址 │");
printf("├──┼───┼─────┼──────┼──────────────────┤");
printf("│%-4s│%-6s│%-10s│%-12s│%-36s│",p->Num,p->Name,p->Oicq,p->Tel,p->Address);
printf("└──┴───┴─────┴──────┴──────────────────┘");
printf("/n/n按任意键返回系统...");
getch();
Exit=TRUE;
}
}
/************************************ SetTitle ***********************************/
void SetTitle()
{
Title[0]=0;
strcat(Title,"☆★☆ ");
strcat(Title,School);
strcat(Title,Yuan);
strcat(Title,"『");
strcat(Title,Class);
strcat(Title,"』同学录 ☆★☆");
}
/************************************ Option *************************************/
void Option()
{
int Exit=FALSE,i,len;
char ch,input[21];
char *str[3]={"学校","院系","班级"};
int nmax[3]={X,Y,Z};
while( !Exit )
{
CLS;
printf("/n/n");
printf(" ╒══════════════════════╕ /n");
printf(" │ ※ 系统设置 │ /n");
printf(" ╞══════════════════════╡ /n");
printf(" │ │ /n");
printf(" │ 学 校: %-12s │ /n",School);
printf(" │ │ /n");
printf(" │ 院 系: %-12s │ /n",Yuan);
printf(" │ │ /n");
printf(" │ 班 级: %-20s │ /n",Class);
printf(" │ │ /n");
printf(" └──────────────────────┘ /n");
printf("/n/n");
printf(" 1:设置学校 2:设置院系 3:设置班级 E:返回系统 /n");
ch=GetChar("123Ee");
if( ch=='E' || ch=='e' )
{
Exit=TRUE;
continue;
}
i=ch-49;
printf("/n/n");
printf("请输入新的%s名称(%d): ",str[i],nmax[i]);
scanf("%s",input);
len=strlen(input);
if ( len > nmax[i] )
{
printf("/n/n溢出错误.输入数据过长.是否继续[Y/N]?");
ch=GetChar("YyNn");
if( ch=='N' || ch=='n')
Exit=TRUE;
continue;
}
switch(i)
{
case 0: strcpy(School,input);break;
case 1: strcpy( Yuan,input) ;break;
case 2: strcpy(Class,input); break;
}
}
SetTitle();
}
/************************************ About *************************************/
void About()
{
/*★☆☆★○●◎◇◆□■△▲※╔ ╗╚ ╝╠ ╣╦ ╩ ╬║═╒ ╕╘ ╛╞ ╡┬ ┴*/
CLS;
printf("/n/n/n/n");
printf(" ╒══════════════════╕ /n");
printf(" │ ※ 关于... │ /n");
printf(" ╞══════════════════╡ /n");
printf(" │ │ /n");
printf(" │ ◇ 同学录管理程序 │ /n");
printf(" │ ◇◆◇ │ /n");
printf(" │ ◇ 版本:1.0 │ /n");
printf(" │ │ /n");
printf(" │ 作者:freewind │ /n");
printf(" │ │ /n");
printf(" │ 版权所有(C) 2006 │ /n");
printf(" │ │ /n");
printf(" └──────────────────┘ /n");
getch();
}
/************************************ Help *************************************/
void Help()
{
CLS;
printf("/n");
printf(" ╒══════════════════════════════╕ /n");
printf(" │ ※ 使用说明 │ /n");
printf(" ╞══════════════════════════════╡ /n");
printf(" │菜单说明: │ /n");
printf(" │ 11 输入档案: 增加新的记录,请按提示的格式输入. │ /n");
printf(" │ 12 删除档案: 删除指定的记录.删除后不能恢复. │ /n");
printf(" │ 13 修改档案: 修改指定的记录.修改后不能恢复. │ /n");
printf(" │ 14 显示全部: 显示全部的记录. │ /n");
printf(" │ 15 退出系统: 保存数据后退出系统. │ /n");
printf(" │ 21 按学号查询: 按学号查询符合条件的记录. │ /n");
printf(" │ 22 按姓名查询: 按姓名查询符合条件的记录. │ /n");
printf(" │ 23 按OICQ查询: 按OICQ查询符合条件的记录. │ /n");
printf(" │ 31 系统设置: 设置系统信息. │ /n");
printf(" │ 41 关于... : 显示程序版本等信息. │ /n");
printf(" │ 42 使用说明: 显示程序使用说明. │ /n");
printf(" │菜单选择: │ /n");
printf(" │ 输入要选择的菜单的编号后回车结束. │ /n");
printf(" │ 例如:要输入档案.输入 11 后回车即可. │ /n");
printf(" │技术支持: │ /n");
printf(" │ 如有问题或建议请联系作者. Email: Freewind22@163.com │ /n");
printf(" │ │ /n");
printf(" └──────────────────────────────┘ /n");
getch();
}
/************************************ Begin *************************************/
void Begin()
{
int Msg;
int Exit=FALSE;
char cMsg[81];
while( !Exit )
{
UI();
printf("/n");
printf("菜单选择:");
scanf("%s",cMsg);
Msg=(cMsg[0]-48)*10+cMsg[1]-48;
switch(Msg)
{
case 11:
InputRecord( 0 ); break;
case 12:
DeleteRecord(); break;
case 13:
ModifyRecord(); break;
case 14:
ListAll(); break;
case 15:
Exit=TRUE; break;
case 21:
SearchRecord( NUM ); break;
case 22:
SearchRecord( NAME ); break;
case 23:
SearchRecord( OICQ ); break;
case 31:
Option(); break;
case 41:
About(); break;
case 42:
Help(); break;
default:
break;
}
}
}
/************************************ End *************************************/
void End()
{
Student * p;
FILE *fp;
CLS;
printf("保存数据中.../n/n");
fp=fopen("Students.ini","w");
if( fp )
fprintf(fp,"%12s %12s %20s/n",School,Yuan,Class);
fp=fopen("Students.dat","w");
if( !fp )
{
printf("数据更新失败.按任意键继续.../n");
getch();
}
while( p=Head )
{
Head=Head->Next;
if( fp )
fprintf(fp,"%4s %6s %10s %12s %36s/n",p->Num,p->Name,p->Oicq,p->Tel,p->Address);
free(p);
}
if( fp )
printf("/n数据保存完毕./n");
fclose(fp);
}
/************************************* Init *************************************/
void Init()
{
FILE *fp;
Student *p;
int ShowHelp=FALSE;
CLS;
printf("读取数据中.../n/n");
fp=fopen("Students.ini","r");
if( !fp )
{
strcpy(School,"南昌大学");
strcpy(Yuan,"继续教育学院");
strcpy(Class,"2005计算机与信息管理");
ShowHelp=TRUE;
}
else
fscanf(fp,"%12s %12s %20s/n",School,Yuan,Class);
fp=fopen("Students.dat","r");
if( !fp )
{
printf("读取数据失败.按任意键继续...");
getch();
}else
{
while ( !feof(fp) )
{
p=(Student *) malloc ( LEN );
Count++;
fscanf(fp,"%4s %6s %10s %12s %36s/n",p->Num,p->Name,p->Oicq,p->Tel,p->Address);
if( !Head )
Head=Last=p;
else
{
Last->Next=p;
Last=p;
}
p->Next=0;
}
fclose(fp);
}
SetTitle();
if( ShowHelp ) Help();
}
/************************************* main *************************************/
void main( int argc, char *argv[] )
{
if( argc>1 && argv[1][0]=='?' )
Help();
Init();
Begin();
End();
}