c++新手问题

ash361 2011-03-01 10:29:05
下面是我改的一个烂图书馆管理系统

其中排序部分的错误一直没有办法排除,希望高手救我

#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#include<iostream.h>
#define N sizeof(struct book)
#define PT "%-5d %10s %6s %6s %8s %3d \n",p->num,p->name,p->where,p->author,p->pub,p->count
struct book //图书信息
{
int num; //书号
char name[10]; //书名
char where[10]; //所在书库
char author[15]; //作者
char pub[20]; //出版社
int count; //数量
struct book *next;
};
//输出模块
void print(struct book *p0)
{
struct book *p;
p=p0->next;
printf("\n\n\t\t^^^^^^^^^^^^^^图书信息表^^^^^^^^^^^^^^");
printf("\n\n图书编号---图书名称---所在书库----作者----出版社---数量\n");
while(p!=NULL)
{
printf(PT);
p=p->next;
}
getch();
}
//输入模块
struct book *creat()
{
struct book *head,*p1,*p2;
int i=0;
head=p2=(struct book *)malloc(N);
head->next=NULL;
printf("\n\n\t\t录入图书信息");
printf("\n\t---------------------------------------");
while(1)
{ p1=(struct book *)malloc(N);
printf("\n 请输入图书编号(书号为0结束): ");
scanf("%d",&p1->num);
if(p1->num!=0)
{
printf("\n\n书名 所在书库 作者 出版社 图书数量\n");
scanf("%s%s%s%s%d",p1->name,p1->where,p1->author,p1->pub,&p1->count);
p2->next=p1;
p2=p1;
i++;
}
else
break;
}
p2->next=NULL;
free(p1);
printf("\n\t\t----------------------------------------");
printf("\n\t\t %d 种书录入完毕",i);
getch();
return head;
}
//查找模块
void find(struct book *p0)
{
char name[10];
int flag=1;
struct book *p;
p=p0->next;
printf("请输入要查找的书名:\n");
scanf("%s",name);
for(p=p0;p;p=p->next)
if(strcmp(p->name,name)==0)
{
printf("\n\n图书编号---图书名称---所在书库----作者----出版社---数量\n");
printf(PT);
flag=0;
break;
}
if(flag) printf("\n 暂无此图书信息\n");
getch();
}
//删除模块
void del(struct book *p0)
{
char name[10];
int flag=1;
struct book *p;
p=p0;
printf("请输入要删除的书名:\n");
scanf("%s",name);
while(p!=NULL)
{
if(strcmp(p->name,name)==0)
{
p0->next=p->next; //后续节点连接到前驱节点之后
free(p);
printf("\t该书资料已删除.");
flag=0;
break;
}
p0=p;
p=p->next;
}
if(flag) printf("\n\t无此图书信息。");
getch();
}
//增加模块
void insert(struct book *p0)
{
struct book *p;
p=(struct book *)malloc(N);
while(1)
{
printf("\n 请输入要增加的图书编号(书号为0 退出): ");
scanf("%d",&p->num);
if(p->num!=0)
{
if(p0->next!=NULL&&p0->next->num==p->num) //找到重复
{
p=p->next;
free(p);
printf("\t该书已存在");
}
else
{printf("\n\n书名 所在书库 作者 出版社 图书数量\n");
scanf("%s%s%s%s%d",p->name,p->where,p->author,p->pub,&p->count);
p->next=p0->next;
p0->next=p;
printf("\t已成功插入.");
}
}
else
break;
}
getch();
}
//修改模块
void modify(struct book *p0)
{
char name[10];
int flag=1;
int choice;
struct book *p;
p=p0->next;
printf("请输入要修改的书名:\n");
scanf("%s",name);
while(p!=NULL&&flag==1)
{
if(strcmp(p->name,name)==0)
{
printf("\n\t请选择要修改的项:");
printf("\n\t 1.修改图书编号\n");
printf("\n\t 2.修改图书所在书库\n");
printf("\n\t 3.修改图书作者\n");
printf("\n\t 4.修改图书出版社\n");
printf("\n\t 5.修改图书库存量\n");
scanf("%d",&choice);
switch(choice)
{
case 1: { printf("\n 请输入新的图书编号:");

scanf("%d",p->num); break;
}
case 2: { printf("\n 请输入新的图书书库:");

scanf("%s",p->where); break;
}
case 3: { printf("\n 请输入新的图书作者:");

scanf("%s",p->author); break;
}
case 4: {printf("\n 请输入新的图书出版社:");

scanf("%s",p->pub); break;
}
case 5: {printf("\n 请输入新的图书库存量:");

scanf("%d",p->count); break;
}
}
printf("\n\t该项已成功修改。\n\t 新的图书信息:");
printf("\n\n图书编号---图书名称---所在书库----作者----出版社---数量\n");
printf(PT);
flag=0;
}
p0=p;
p=p0->next;
}
if(flag) printf("\n\t暂无此图书信息。");
getch();
}
//排序模块
struct sort(struct book *p0) //按数量排序
{
struct book *w,*t,*h,*q;
w=p0->next; //将原表的头指针所指的下一个结点作头指针
p0->next=NULL; //第一个结点为新表的头结点
while(w!=NULL)
{
t=w; //取原表的头结点
w=w->next; //原表头结点指针后移
h=p0; //设定移动指针h,从头指针开始
q=p0; //设定移动指针q做为h的前驱,初值为头指针
while((t->count)>(h->count) && h!=NULL) //作数量比较
{
q=h;
h=h->next;
}
if(h==q)
{
t->next=h;
p0=t;
}
else //待排序点应插入在中间某个位置q和h之间,如h为空则是尾部
{
t->next=h; //t的后继是h
q->next=t; //q的后继是t
}
}
printf("排列完毕!\n");
return p0; //返回头指针
}

//借书
void bor(struct book *p0)
{
char name[10];
int flag=1;
struct book *p;
p=p0->next;
printf("请输入要出借的书名:\n");
scanf("%s",name);
while(p!=NULL&&flag==1)
{
if(strcmp(p->name,name)==0)
{
if(p->count>0){
p->count=(p->count)-1;
}
printf("\n\t借出成功\n\t 新的图书信息:");
printf("\n\n图书编号---图书名称---所在书库----作者----出版社---数量\n");
printf(PT);
flag=0;
}
p0=p;
p=p0->next;
}
if(flag) printf("\n\t暂无此图书信息。");
getch();
}
//还书
void ret(struct book *p0)
{
char name[10];
int flag=1;
struct book *p;
p=p0->next;
printf("请输入要归还的书名:\n");
scanf("%s",name);
while(p!=NULL&&flag==1)
{
if(strcmp(p->name,name)==0)
{
if(p->count>0){
p->count=(p->count)+1;
}
printf("\n\t归还成功\n\t 新的图书信息:");
printf("\n\n图书编号---图书名称---所在书库----作者----出版社---数量\n");
printf(PT);
flag=0;
}
p0=p;
p=p0->next;
}
if(flag) printf("\n\t暂无此图书信息。");
getch();
}


//读文件
struct book *read_file()
{
int i=0;
struct book *p,*p1,*head=NULL;
FILE *fp;
if((fp=fopen("library.txt","rb"))==NULL)
{printf("\n\n\n\n\n \t********库文件不存在,请创建!**********");
getch();
return NULL;
}
head=(struct book *)malloc(N);
p1=head;
head->next=NULL;
printf("\n 已有图书信息:");
printf("\n\n图书编号---图书名称---所在书库----作者----出版社---数量\n");
while(!feof(fp))
{
p=(struct book *)malloc(N); //开辟空间以存放的取得信息
while(fscanf(fp,"%d%s%s%s%s%d",&p->num,p->name,p->where,p->author,p->pub,&p->count)!=EOF)
{
printf(PT);
i++;
}
p1->next=p;
p1=p;
}
p1->next=NULL;
fclose(fp);
printf("\n 共种%d 图书信息",i);
printf("\n\n\n 文件中的信息以正确读出。按任意键进入主菜单。");
getch();
return (head);
}
//保存文件
void save(struct book *head)
{
FILE *fp;
struct book *p;
fp=fopen("library.txt","wb"); //以只写方式打开二进制文件
if(fp==NULL) //打开文件失败
{
printf("\n=====>打开文件失败!\n");
getch();
return ;
}
else
for(p=head->next;p!=NULL;p=p->next)
fprintf(fp,"%d %s %s %s %s %d\n",p->num,p->name,p->where,p->author,p->pub,p->count);
fclose(fp);
printf("\n\t保存文件成功!\n");
}
void main()
{
struct book *head=NULL;
int choice=1;
head=read_file();
if(head==NULL)
{
printf("\n\t\t**********");
getch();
head=creat();
}
do
{
system("cls");
printf("\t\t----------Welcome---------\n");
printf("\n\n\t欢迎您,图书管理员.\n");
printf("\n\n\n\n\n");
printf("\n\t 请选择:(修改图书信息后需退出保存,否则会丢失修改讯息)");
printf("\n\t 1.查询图书信息\n");
printf("\n\t 2.修改图书信息\n");
printf("\n\t 3.增加图书信息\n");
printf("\n\t 4.删除图书信息\n");
printf("\n\t 5.显示所有图书信息\n");
printf("\n\t 6.排序所有图书\n");
printf("\n\t 7.借阅图书\n");
printf("\n\t 8.归还图书\n");
printf("\n\t 0.退出系统\n");
scanf("%d",&choice);
switch(choice)
{
case 1: find(head); break;
case 2: modify(head); break;
case 3: insert(head); break;
case 4: del(head); break;
case 5: print(head); break;
case 6: sort(head); break;
case 7: bor(head); break;
case 8: ret(head); break;
case 0: system("cls");
printf("\n\n\n\n\n\t^^^^^^^^^^谢谢使用,再见^^^^^^^^^^!\n\n");
break;
}
}while(choice!=0);
save(head);
}
...全文
139 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
雪人2015 2011-03-02
  • 打赏
  • 举报
回复
建议看经典书籍的案例。

或者直接自己写一个。
ash361 2011-03-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 newfarmerchi 的回复:]
C/C++ code


//用这个模块试一下,程序运行应当不会崩溃了。
struct book* sort(struct book *p0) //返回book*
{
struct book *w,*t,*h=NULL;
while(p0->next!=h)
{
w=p0;
t=p0->next;
while(t->nex……
[/Quote]

旧的问题还没解决新的又来了,现在保存,动不动就输出一个300多M的txt,我都快疯了
雪人2015 2011-03-02
  • 打赏
  • 举报
回复
怎么感觉遍历算法风格不统一!

而且变量命名很是问题。让人根本不知道变量的实际用处,必须仔细阅读才能够明白变量的意义。例如:
int nFlag;为何不定义bool bFind;

读了一半,读不下去了!
qq120848369 2011-03-02
  • 打赏
  • 举报
回复
自己慢慢学吧,大一新生都是迷茫的
ash361 2011-03-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 npuhuxl 的回复:]
h=p0; //设定移动指针h,从头指针开始
q=p0; //设定移动指针q做为h的前驱,初值为头指针

如果你的头指针不存储数据的话
h =p0->next; //这样才是第一个数据
q = h;//或者是q=p0,这样后面就不用判断q==h了

LZ代码写的不错!值得表扬
[/Quote]

。。。。。。。。。不是我写的,我只是“借鉴”了几个程序然后重新创作
newfarmerchi 2011-03-02
  • 打赏
  • 举报
回复


//用这个模块试一下,程序运行应当不会崩溃了。
struct book* sort(struct book *p0) //返回book*
{
struct book *w,*t,*h=NULL;
while(p0->next!=h)
{
w=p0;
t=p0->next;
while(t->next!=h)
{
if ((w->next->count) > (t->next->count))//作数量比较
{
w->next=t->next;
t->next=w->next->next;
w->next->next=t;
w=w->next;
}
else
{
w=t;
t=t->next;
}

}
h=t;
}

printf("排列完毕!\n");
system("pause");//加个它

return p0; //返回头指针
}


ash361 2011-03-02
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 newfarmerchi 的回复:]
我看了一下,发现问题有两个:
1.你存入的文件格式是for(p=head->next;p!=NULL;p=p->next)
fprintf(fp,"%d %s %s %s %s %d\n",p->num,p->name,p->where,p->author,p->pub,p-
>count);
"%d %s %s %s %s %d\n"
而读的格式是这个"%d%s%s……
[/Quote]

哇,终于可以了,好开心,谢谢你啊
果冻想 2011-03-02
  • 打赏
  • 举报
回复
如何需要,可以联系我,我可以给你写一个。QQ:535064959
newfarmerchi 2011-03-02
  • 打赏
  • 举报
回复
我看了一下,发现问题有两个:
1.你存入的文件格式是for(p=head->next;p!=NULL;p=p->next)
fprintf(fp,"%d %s %s %s %s %d\n",p->num,p->name,p->where,p->author,p->pub,p-
>count);
"%d %s %s %s %s %d\n"
而读的格式是这个"%d%s%s%s%s%d",应当也改为"%d %s %s %s %s %d\n"。
2.while(fscanf(fp,"%d%s%s%s%s%d",&p->num,p->name,p->where,p->author,p->pub,&p->count)!=EOF)
这里不应该是一个循环,这也是为什么只打出最后一个值的原因,因为fp一下子
跑到最后了。应该只是fscanf(fp,"%d %s %s %s %s %d\n",&p->num,p->name,p->where,p->author,p->pub,&p->count);
以下是改后的读文件模块
//读文件
struct book *read_file()
{
int i=0;
struct book *p,*p1,*head=NULL;
FILE *fp;
if((fp=fopen("library.txt","rb"))==NULL)
{printf("\n\n\n\n\n \t********库文件不存在,请创建!**********");
getch();
return NULL;
}
head=(struct book *)malloc(N);
p1=head;
head->next=NULL;
printf("\n 已有图书信息:");
printf("\n\n图书编号---图书名称---所在书库----作者----出版社---数量\n");

while(!feof(fp))
{
p=(struct book *)malloc(N); //开辟空间以存放的取得信息
fscanf(fp,"%d %s %s %s %s %d\n",&p->num,p->name,p->where,p->author,p->pub,&p->count);
printf(PT);
i++;
p1->next=p;
p1=p;
}
p1->next=NULL;
fclose(fp);
printf("\n 共种%d 图书信息",i);
printf("\n\n\n 文件中的信息以正确读出。按任意键进入主菜单。");
getch();
return (head);
}

这个运行时正常的。
ash361 2011-03-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 newfarmerchi 的回复:]
你试一下不运行head=read_file()和save(head);看看如何?
[/Quote]

出现那种情况的原因我搞清楚了,输入的时候必须要用回车分隔开数据,否则就会保存失败,创建出一个无限大的txt

现在是显示的部分有问题,每次显示都会把其他的数据删掉,只留下最大的一个

有没有办法可以把一开始读文件的显示调用到显示全部哪里??

newfarmerchi 2011-03-02
  • 打赏
  • 举报
回复
你试一下不运行head=read_file()和save(head);看看如何?
npuhuxl 2011-03-01
  • 打赏
  • 举报
回复
h=p0; //设定移动指针h,从头指针开始
q=p0; //设定移动指针q做为h的前驱,初值为头指针

如果你的头指针不存储数据的话
h =p0->next; //这样才是第一个数据
q = h;//或者是q=p0,这样后面就不用判断q==h了

LZ代码写的不错!值得表扬

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧