用C语言实现一个类似学籍管理系统的 e协 管理系统beta ( 正在完善中...)
搞了很久, 终于搞出点眉目了, 不过还需要大大改进. /**-------------------------exie.h------------------**/
#ifndef _EXIEBETA_H_
#define _EXIEBETA_H_
/****************************************/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define SIZE sizeof ( struct member )
#define newMember (Member)malloc(SIZE)
#define FORMAT "/tID/t name /t sex/tage/tclass/
/t/tlevel/tStatus/t/t Achievement /n"
char _[] = "***********************************************/
*************************************/n";
char FILENAME[] = "c://ememberinfo.emi";
char systemMsg[] =
"/n/t/t********************************************/n/t/
/t* E-System */n/t/
/t* version 1.0 */n/t/
/t*------------------------------------------*/n/t/
/t* By: lonelyforest */n/t/
/t* QQ: 36274668 */n/t/
/t* E-mail: lonelyforest@126.com */n/t/
/t********************************************/n";
char helpMSG[] = "/n-----------------------------------------------/n/t/
0. help/n/t/
1. display all members' information/n/t/
2. Record into the information/n/t/
3. Search members' information/n/t/
4. Delete members' information/n/t/
5. Exit this system/n/t/
9. System information/n/
-----------------------------------------------/n/n";
static int id = 0 ; /*为每个会员分配唯一的ID号*/
typedef struct member{
int id;
char name[20];
char sex;
int age;
char class[20];
int level;
char statu[20];
char achievement[50];
struct member *next;
} *Member;
/*****---------------------****/
/*** 用于接收数据的辅助函数, 可用于查找和录入信息 **/
Member get_msg()
{
Member p = newMember;
if ( !p ) {printf("/n malloc errer.../n"); exit(0);}
printf("/nplease input members' information:/n");
printf("ID (number):");
scanf("%d", &p->id);
printf("name : ");
scanf("%s", p->name) ;
printf("sex (f/m):");
p->sex = getch();
printf("%c", p->sex);
printf("/nage (number):");
scanf("%d", &p->age);
printf("class :");
scanf("%s", p->class);
printf("level (integer):");
scanf("%d", &p->level);
printf("statu :");
scanf("%s", p->statu);
printf("achievement : ");
scanf("%s", p->achievement);
p->next = NULL;
return p;
}
/** 创建记录辅助函数, */
Member create_member()
{
Member p;
p=newMember;
if( !p ) {printf("/n malloc errer..../n"); exit(0);}
p->id = id++;
strcpy(p->name, "unnamed");
p->sex = 'm';
p->age = 21;
strcpy(p->class, "class1");
p->level = 0; /*级别 */
strcpy(p->statu, "member"); /*身份 */
strcpy(p->achievement, " have not achievenment");
p->next = NULL;
printf("create_member()%d/n",p->id);
return p;
}
/* 存储函数辅助 , count = 0表示全部 存储, bufferHead 为缓冲头指针,
* rw 表示存储方式, "wb", "ab" , "wb+";
*/
void save(Member bufferHead, FILE *fp, int count, char *rw )
{
Member p = bufferHead->next;
if ( count == 0 ) {
/*如果是附加方式则关闭以前指针重新打开一个附加型指针 */
if ( !strcmp(rw, "ab" ) ) {
fclose(fp);
fp = fopen( FILENAME, "ab" );
}else {
fclose(fp);
fp = fopen( FILENAME, "wb" );
}
while ( p ) {
if ( fwrite( p, SIZE, 1, fp) != 1 ) {
printf(" write errer /n" );
break;
}
p = p->next;
}
} else {
{ /*如果是附加方式则关闭以前指针重新打开一个附加型指针 */
if ( !strcmp(rw, "ab" ) )
fclose(fp);
fp = fopen( FILENAME, "ab" );
}else {
fclose(fp);
fp = fopen( FILENAME, "wb" );
}
while ( p && count--){
if ( fwrite( p, SIZE, 1, fp) != 1 ) {
printf(" write errer /n" );
break;
}
p = p->next;
}
}
}
/*************读入函数, 用参数 count 控制读入数量
* 将数据读入到 内存, */
void load( Member bufferHead, FILE *fp, int count )
{
Member q, end, p = bufferHead;
int i;
if ( count != 0 ){
for ( i = 0; i < count && !feof(fp); ++i) {
q = newMember;
q->next = NULL;
p->next = q;
p=p->next;
if (fread(q, SIZE, 1, fp) != 1) /*因为feof(fp)返回的是文件结束 */
{
/*信号, 所以这之前读的最后一个为错误值*/
p->next = NULL;
free(q);
break;
}
}
} else {
while ( !feof(fp) ) {
q = newMember;
q->next = NULL;
p->next = q;
if (fread(q, SIZE, 1, fp) != 1)
{
p->next = NULL;
free(q);
break;
}
p = p->next;
}
}
}
/************辅助函数,用于输出, 用参数控制输出个数****/
void show( Member bufferHead, int count ) /*count = 0 表示全部输出. */
{
Member p = bufferHead->next;
int i = 0;
if ( count == 0 ) {
printf(FORMAT);
while(p != NULL) {
printf("%d/t%d/t%s/t %c /t%d/t%s/t/t %d/t%s/t/t%s/n",i++,
p->id, p->name,p->sex,p->age,p->class,
p->level, p->statu, p->achievement );
p = p->next;
}
} else {
for ( i = 0; i< count && p; ++i ) {
printf("%d/t%d/t%s/t %c /t%d/t%s/t/t %d/t%s/t/t%s/n",i,
p->id, p->name,p->sex,p->age,p->class,
p->level, p->statu, p->achievement );
p = p->next;
}
}
}
/************查找辅助函数, 返回找到值的前驱指针,否则返回空指针****
************返回前驱,主要有利于条件删除 ***********************/
Member find_if( const Member head, const Member val )
{
Member p = head;
Member q = NULL;
while ( p && p->next ) {
q = p;
p = p->next;
if ( ((p->id == val->id )
|| !strcmp(p->name, val->name))
&& p->sex == val->sex )
break;
if ( !p->next ) {
q = NULL;
break;
}
}
return q;
}
/* 以下函数主要用于测试是否存在存档文件, 如果没有, 则提示用户创建*/
int testfile()
{
FILE *fp;
if ( (fp = fopen( FILENAME, "rb" )) == NULL )
{
printf("这是您第一次运行本程序, 程序将会创建数据文件..%s/n",FILENAME );
if ( (fp = fopen( FILENAME, "wb" )) == NULL ){
printf(" create file fail..... " );
return -1;
}
fclose(fp);
printf("/nfile has created .../n");
return 0;
}
return 0;
}
void free_memery( Member head )
{
Member p = head->next;
Member q;
while(p != NULL )
{
q = p;
p = p->next;
free(q);
}
}
/*******显示所有数据 *********/
void Display( )
{
struct member head;
FILE *fp;
if ( (fp = fopen(FILENAME, "rb")) == NULL )
{
printf( " cannot find the file %s/n", FILENAME);
return ;
}
printf("display/n/t/t/t/tresultes/n%s",_);
load(&head, fp, 0 );
fclose(fp);
show(&head, 0);
printf("%s",_);
free_memery(&head);
}
/*********查找函数,利用辅助查询函数
*********Member find_if( Member head, const Member val )
*********来接收查询到位置的前驱, 并且存储在新建连表中 */
void Search( ) /*需要输入查询条件*/
{
struct member bufferHead, foundHead;
Member val, found, p, q, temp;
FILE *fp;
val = found = p = q = temp = NULL;
foundHead.next = NULL;
printf("Search/n");
if ( (fp = fopen(FILENAME, "rb")) == NULL )
return ;
else {
load( &bufferHead, fp, 0 );
if ( ferror(fp) ) {
printf("...........file operate error......./n");
return ;
}
fclose(fp);
printf("please input the members' information,/
id or name, and sex is necessary.../n");
val = get_msg();
p = &bufferHead;
found = &foundHead;
while ( p ) {
if (( temp = find_if(p, val )) != NULL ) {
temp = temp->next;
p = temp;
q = newMember;
*q = *temp;
q->next = NULL;
found->next = q;
found = found->next;
}
else break;
}
if ( foundHead.next ) {
printf("/n/t/t/tthe founded information/n%s",_);
show(&foundHead, 0);
printf("%s/n", _);
} else {
printf(" ............no one has searched .........../n");
}
}
/****分别释放查询结果内存和文件缓冲内存
*****以免内存泄露 */
free_memery(&foundHead);
free_memery(&bufferHead);
}
void Record()
{
FILE *fp;
struct member head;
Member p,q;
char ch;
printf("Record/n");
if ( (fp = fopen(FILENAME, "ab")) == NULL )
{
printf( " cannot find the file %s", FILENAME);
return;
}
p=&head;
printf("please members' information/n");
do {
q = get_msg();
/*q = create_member();*/
p->next = q;
p = p->next;
printf("/n do you want to input another member ? (y/n) : ");
ch = getch();
printf("%c", &ch);
} while ( ch == 'y' || ch == 'Y' );
save(&head, fp, 0, "ab");
free_memery(&head);
fclose(fp);
}
/***********需要输入删除条件否则删除所有内容**********/
void Drop( )
{
FILE *fp;
struct member bufferHead;
Member p,q;
char ch[2];
bufferHead.next = NULL;
printf(
" Delete /n Please choose :/n/t/
0. delete all data/n/
/t1. delete a member/nchoose :");
scanf("%s", ch);
if( ch[0] == '0' ) {
if ( (fp = fopen( FILENAME, "wb" )) == NULL ) {
printf("/ndelete file fail..../n");
} else printf("/nall data has deleted..../n");
return;
} else if ( ch[0] == '1' ){
if ( (fp = fopen( FILENAME, "rb+" )) == NULL ) {
printf(" open file %s error....../n", FILENAME);
return;
}
load( &bufferHead, fp, 0 );
q = get_msg();
p = find_if( &bufferHead, q);
free(q);
while ( p ) {
q = p;
p = p->next;
q->next = p->next;
free(p);
}
save( &bufferHead, fp, 0, "wb");
free_memery(&bufferHead);
fclose(fp);
}
else printf(" donot understand ..../n");
}
/************************************/
#endif
//-----exie.c
#include "exiebeta.h"
int main(int argc, char *argv[])
{
char choose;
printf("%s", systemMsg);
/***测试是否存在存档文件***/
choose = testfile();
if ( choose == 0 ){
printf( "/n%s", helpMSG);
do {
printf("please choose: ");
choose = getch();
switch ( choose - 48 ) {
case 5: exit(0);
case 0: printf("%s", helpMSG); break;
case 1: Display(); break;
case 2: Record(); break;
case 3: Search(); break;
case 4: Drop(); break;
case 9: printf("%s", systemMsg); break;
default:
printf("/ncannot understand your command, please choose again!!/n" );
break;
}
} while ( 1 );
}
system("PAUSE");
return 0;
}
/*** 档案文件存储在 c 盘下面. 不过有个问题没解决,就是关于 id 号重复, 的问题, 当然还有很多,比如查询的问题,以及删除时所牵扯到的细节.我会不断完善,希望大家能够支持并且评论.