首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

C语言方面的,因本人是初学C者,这是自己编的图书管理系统中的一部分代码,编码方面没有关问题,但就是运行的时候,每当要排序时无法进行有效的排序,请懂得人帮忙看下

2013-07-08 
C语言方面的求助,因本人是初学C者,这是自己编的图书管理系统中的一部分代码,编码方面没问题,但就是运行的

C语言方面的求助,因本人是初学C者,这是自己编的图书管理系统中的一部分代码,编码方面没问题,但就是运行的时候,每当要排序时无法进行有效的排序,请懂得人帮忙看下

 
/* Note:Your choice is C IDE */
#include "stdio.h"   /*标准输入输出函数库*/
#include "stdlib.h"  /*标准函数库*/
#include "string.h"  /*字符串函数库*/
#include "conio.h"    /*屏幕操作函数库*/
#define HEADER1 "   |--------------------------------图书信息表------------------------|\n\n"
#define HEADER2 "   | 登录号| 书名 | 作者名 |分类号|出版单位|     出版时间      | 价格  | \n"
#define HEADER3 "   |-------|------|--------|------|--------|-------------------|-------| \n"
#define FORMAT  "   |   %s  |  %s  |   %s   |  %s  |  %s    |     %9s    |  %s  |\n"
#define DATA  p->data.bookID,p->data.bookname,p->data.author,p->data.booktype,p->data.publisher,p->data.time,p->data.price
#define END     "    ----------------------\n"
int saveflag=0;  /*是否需要存盘的标志变量*/

/*定义与图书有关的数据结构*/
typedef struct book      /*标记为book*/
{
char bookID[16];        /*登录号*/
char bookname[16];      /*书名*/
char author[16];        /*作者名*/
char booktype[16];      /*分类号*/
char publisher[16];     /*出版单位*/
char time[16];          /*出版时间*/
    char price[16];         /*价格*/
};



/*定义每条记录或结点的数据结构,标记为:node*/
typedef struct node
{
struct book data;  /*数据域*/
struct node *next;    /*指针域*/
}Node,*Link;   /*Node为node类型的结构变量,*Link为node类型的指针变量*/


void menu()  /*主菜单*/
{
system("cls");   /*调用DOS命令,清屏.与clrscr()功能相同*/
printf("\n\n               广东工业大学商学院图书信息管理系统                \n");
    printf("     *************************菜单*********************************\n");
    printf("     *1 输入图书信息                  6 修改图书信息            *\n");


    printf("     *2 打印图书信息                  7 插入图书信息            *\n");
    printf("     *3 排序图书信息                  8 删除图书信息            *\n");
    printf("     *4 统计图书信息                  9 保存图书信息            *\n");
    printf("     *5 查找图书信息                  0 退出系统                *\n");
    printf("     **************************************************************\n");
}



/* ------------------printheader函数,格式化表头-------------------------*/
void printheader() /*格式化输出表头*/
{
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
}



/* -----------------------printdata函数,格式化输出数据-----------------*/
void printdata(Node *pp) /*格式化输出表中数据*/
{
Node* p;
p=pp;
printf(FORMAT,DATA);

}



/* ------------------------------Wrong函数,输出按键错误信息---------------------*/
void Wrong()  /*输出按键错误信息*/
{
printf("\n\n\n\n\n***********错误!:输入发生错误!请按任意键继续**********\n");
getch();
}



/*--------------------------- NOfind函数,用于输出未查找此图书的信息-----------------------*/
void Nofind()  /*输出未查找此图书的信息*/
{
printf("\n=====>没有找到此图书!\n");
}



/*---------------------------------------- Disp函数---------------------------------*/
void Disp(Link l)  /*显示单链表l中存储的图书记录,内容为book结构中定义的内容*/
{
Node *p;
p=l->next; /*l存储的是单链表中头结点的指针,该头结点没有存储图书信息,指针域指向的后继结点才有图书信息*/
if(!p)  /*p==NULL,NUll在stdlib中定义为*/
{
printf("\n=====>没有图书数据!\n");
getch();
return;
}
printf("\n");
printheader(); /*输出表格头部*/

while(p)    /*逐条输出链表中存储的图书信息*/
{   
printdata(p);
p=p->next;  /*移动直下一个结点*/
printf(HEADER3);
}
getch();
}
/*************************************************************
作用:用于定位链表中符合要求的节点,并返回指向该节点的指针


参数:findmess[]保存要查找的具体内容; booknameorbookID[]保存按什么查找;
      在单链表l中查找;
**************************************************************/
Node* Locate(Link l,char findmess[],char booknameorbookID[])
{
Node *r;
if(strcmp( booknameorbookID,"bookID")==0) /*按登录号查询*/
{
r=l->next;
while(r)
{
if(strcmp(r->data.bookID,findmess)==0) /*若找到findmess值的登录号*/
return r;
r=r->next;
}//结束while(r)
}//结束if(strcmp(booknameorbookID,"bookID")==0)

else if(strcmp(booknameorbookID,"bookname")==0)  /*按书名查询*/
{
r=l->next;
while(r)
{
if(strcmp(r->data.bookname,findmess)==0)    /*若找到findmess值的图书书名*/
return r;
r=r->next;
}//结束while(r)
}//结束else if(strcmp(booknameorbookID,"bookname")==0)
return 0; /*若未找到,返回一个空指针*/
}//结束Node* Locate(Link l,char findmess[],char booknameorbookID[])




/*输入字符串,并进行长度验证(长度<lens)*/
void stringinput(char *t,int lens,char *notice)
{
   char n[255];
   do{
printf(notice);  /*显示提示信息*/
scanf("%s",n);  /*输入字符串*/
if(strlen(n)>lens) printf("\n 超出要求长度! \n");/*进行长度校验,超过lens值重新输入*/
     }while(strlen(n)>lens);
  strcpy(t,n); /*将输入的字符串拷贝到字符串t中*/
}




     /*---------------------------------增加图书记录-----------------------------------*/
void Add ( Link l ) 
{
Node *p,*r,*s;  /*实现添加操作的临时的结构体指针变量*/
char ch,flag=0,bookID[16];
r=l;
s=l->next;
system("cls");
Disp(l); /*先打印出已有的图书信息*/
while(r->next!=NULL)
r=r->next; /*将指针移至于链表最末尾,准备添加记录*/
while(1) /*一次可输入多条记录,直至输入登录号为的记录结点添加操作*/
{
while(1) /*输入登录号,保证该登录号没有被使用,若输入登录号为,则退出添加记录操作*/
{
stringinput(bookID,16,"\n输入登录号(输入返回菜单):"); /*格式化输入登录号并检验*/
flag=0;

if(strcmp(bookID,"0")==0) /*输入为0,则退出添加操作,返回主界面*/
{
return;
}

s=l->next;
while(s) /*查询该登录号是否已经存在,若存在则要求重新输入一个未被占用的登录号*/
{
if(strcmp(s->data.bookID,bookID)==0)
{
flag=1;
break;
}
s=s->next;
}
if(flag==1) /*提示用户是否重新输入*/
{  
getch();
printf("=====>登录号%s不存在,再试一次? (是(y)/否(n)):",bookID);
scanf("%c",&ch);
if(ch=='y'||ch=='Y')continue;
else
return;
}
else
{
break;
}
}


p=(Node *)malloc(sizeof(Node)); /*申请内存空间*/
if(!p)
{
printf("\n allocate memory failure "); /*如没有申请到,打印提示信息*/
return ;             /*返回主界面*/
 }

strcpy(p->data.bookID,bookID); /*将字符串bookID拷贝到p->data.bookID*/
stringinput(p->data.bookname,16,"书名:");      /*输入书名*/
stringinput(p->data.author,16,"作者名:");      /*输入作者名*/
stringinput(p->data.booktype,16," 分类号:");   /*输入分类号*/
stringinput(p->data.publisher,16," 出版单位:");    /*输入出版单位*/
stringinput(p->data.time,16," 出版时间:");     /*输入出版时间*/
stringinput(p->data.price,16," 价格:");        /*输入价格*/
        p->next=NULL; /*表明这是链表的尾部结点*/
r->next=p;  /*将新建的结点加入链表尾部中*/
r=p;
saveflag=1;
}
    return ;
}

  /*---------------利用插入排序法实现单链表的按总分字段的降序排序,从高到低----------------*/
void Sort(Link l)
{
Link ll;
Node *p,*rr,*s;
int i=0;
if(l->next==NULL)

system("cls");
printf("\n=====>没有学生记录!\n");
getch();
return ;
}

ll=(Node*)malloc(sizeof(Node)); /*用于创建新的节点*/
if(!ll)
{
      printf("\n allocate memory failure "); /*如没有申请到,打印提示信息*/
      return ;             /*返回主界面*/
}

ll->next=NULL;
system("cls");
Disp(l);  /*显示排序前的所有学生记录*/
printf("\n排序后:\n");
p=l->next;
while(p) /*p!=NULL*/
{
 s=(Node*)malloc(sizeof(Node)); /*新建节点用于保存从原链表中取出的节点信息*/
if(!s) /*s==NULL*/
{      
printf("\n allocate memory failure "); /*如没有申请到,打印提示信息*/
return ;   
}  

/*返回主界面*/
s->data=p->data; /*填数据域*/
s->next=NULL;    /*指针域为空*/
rr=ll;

/*rr链表于存储插入单个节点后保持排序的链表,ll是这个链表的头指针,每次从头开始查找插入位置*/
while(rr->next!=NULL && rr->next->data.bookID>=p->data.bookID)
{
rr=rr->next;
} /*指针移至总分比p所指的节点的总分小的节点位置*/

if(rr->next==NULL)/*若新链表ll中的所有节点的总分值都比p->data.total大时,就将p所指节点加入链表尾部*/
rr->next=s;
else /*否则将该节点插入至第一个总分字段比它小的节点的前面*/
{   
s->next=rr->next;
rr->next=s;  


}

p=p->next; /*原链表中的指针下移一个节点*/
}

l->next=ll->next; /*ll中存储是的已排序的链表的头指针*/


Disp(l);
saveflag=1;
printf("\n    =====>排序完成!\n");
}
  
/*---------数据存盘,若用户没有专门进行此操作且对数据有修改,在退出系统时,会提示用户存盘----*/
void Save(Link l)
{
FILE* fp;
Node *p;
int count=0;
fp=fopen("c:\\book","wb");/*以只写方式打开二进制文件*/
if(fp==NULL) /*打开文件失败*/
{
printf("\n=====>文件打开失败!\n");
getch();
return ;
}
p=l->next;
while(p)
{
if(fwrite(p,sizeof(Node),1,fp)==1)/*每次写一条记录或一个节点信息至文件*/
{   
p=p->next;
count++;  
}
else
{   
break;
}
}

if(count>0)
{  
getch();
printf("\n\n\n\n\n=====>保存文件完成,总的图书数是:%d\n",count);
getch();
saveflag=0;}
else
{
system("cls");
printf("当前链接为空,没有图书记录被保存!\n");
getch();
}
fclose(fp); /*关闭此文件*/
}


/*--------------------------------主函数--------------------------――――---------*/
void main()
{  
Link l;      /*定义链表*/
FILE *fp;    /*文件指针*/
int select;     /*保存选择结果变量*/
char ch;     /*保存(y,Y,n,N)*/
int count=0; /*保存文件中的记录条数(或结点个数)*/
Node *p,*r;   /*定义记录指针变量*/
l=(Node*)malloc(sizeof(Node));

if(!l)
 {      
printf("\n allocate memory failure "); /*如没有申请到,打印提示信息*/
return ;   
} /*结束  if(!l) */        /*返回主界面*/

l->next=NULL;
r=l;
fp=fopen("C:\\book","ab+"); /*以追加方式打开一个二进制文件,可读可写,若此文件不存在,会创建此文件*/

if(fp==NULL)
{   
printf("\n=====>不能打开文件!\n");
exit(0);
}//结束if(fp==NULL)

while(!feof(fp))

p=(Node*)malloc(sizeof(Node));
if(!p)
{  
printf(" memory malloc failure!\n");    /*没有申请成功*/
exit(0);       /*退出*/
}//结束if(!p)

if(fread(p,sizeof(Node),1,fp)==1) /*一次从文件中读取一条图书信息记录*/
{
p->next=NULL;
r->next=p;
r=p;                            /*r指针向后移一个位置*/
count++;   
}//结束if(fread(p,sizeof(Node),1,fp)==1)

}//结束while(!feof(fp))



fclose(fp); /*关闭文件*/
printf("\n=====>打开文件成功,总的图书数目是: %d.\n",count);

menu();//调用主菜单函数

while(1)
{   
system("cls");
menu();//根据数字 调用主菜单函数
p=r;
printf("\n              请输入你的选择(0~9):");    /*显示提示信息*/
scanf("%d",&select);
if(select==0)
{   
if(saveflag==1) /*若对链表的数据有修改且未进行存盘操作,则此标志为*/

getch();
printf("\n=====>是否保存修改到文件?  是(y)/否(n):");
scanf("%c",&ch);
if(ch=='y'||ch=='Y')Save(l);
}//结束if(saveflag==1) 

printf("\n=====>商学院电商12班制作!\n\n=====>谢谢您的使用!\n");
getch();
break;
}//结束if(select==0)

 switch(select)//根据你选择的数字,调用相应的9个函数
{  
case 1:Add(l);break;           /*第1个函数  增加图书记录*/

case 2:system("cls");Disp(l);break;          /*第2个函数  显示图书记录*/
default: Wrong();getch();break;        /*按键有误,必须为数值-9*/
}//结束switch
}/*结束while(1)*/              

}//主函数结束

C 图书 管理 编码 printf
[解决办法]
你的 Locate 找到一个就退出的吗, 那你外面用一个循环来反复调用吧,
仅供参考:


    else if(select==2) /*按作者名查询*//*第二种情况*/
    {
        stringinput(searchinput,16,"请输入已存在图书的作者名:");
        p=Locate(l,searchinput,"author");
        while(p)
        {
            printheader();
            printdata(p);
            printf(END);


            if(!p->next)
                break;
            p=Locate(p->next,searchinput,"author"); // 注意这里传 p->next, 不是 l
         }
         printf("请按任意键返回");
         getch();
    }


热点排行