写了一个链表,但是排序出现了问题,求教大佬

Orisland 学生  2019-06-21 10:10:54
c语言的一个作业,编写一个图书管理系统
要求用链表,
写是写出来了,但是出现了问题。
代码太长了……去掉了页面部分发出来了。
namesort函数是排序函数,我的目的是让链表实现按照汉字首字母来排序
因为使用了两个结构体叠在一起,所以我的排序方法是,
对换bookdata,以实现对换的目的
但是当我输入数据实验的时候……
输出3个数据正常,4个数据正常,
输入5个数据,则第五个数据一定会出错变成问号……
如果这个时候储存,再一次运行,
那么则会增加一个问号数据,也就是再次丢失第五个数据……其他数据完好。
还请大佬们,帮忙看看,这个排序到底是哪出问题了,为什么总是在第五个数据出现问题,而其他的没问题……

(代码调用函数,只需要调整主函数的//的位置就好)
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <conio.h>

struct bookdata
{
char bookname[100]; //书名
char bookid[100]; //书的编号
char publisher[100]; //书的出版社
float price; //书价格
char adddate[10]; //书的上架日期
char outdate[10]; //书的下架日期
int source; //书的来源
int direction; //书的去向
int kind; //书的种类
int num; //书的库存数量
};

typedef struct Tbook
{
struct bookdata Bdata;
struct Tbook *pNext;
} Book,* pBook;

pBook add(pBook);
pBook searchName(pBook pHead);
pBook searchName1(pBook pHead);
pBook searchID(pBook pHead);
pBook searchID1(pBook pHead);
pBook searchKind(pBook pHead);
pBook CreateList();
void save(pBook pHead);
void output(pBook pHead);
void singleoutput(pBook pHead);
void back();
pBook del(pBook pHead);
void namesort(pBook pHead);

int main(void)
{
pBook pHead = NULL;
pHead = CreateList();
printf("从文件中读取完毕\n");
//add(pHead);
//output(pHead);
//save(pHead);
//del(pHead);
output(pHead);
namesort(pHead);
output(pHead);

return 0;
}

pBook add(pBook pHead)
{
int i;
int len;

pBook pTail = pHead;
pTail->pNext = NULL;

printf("输入需要添加书的数量:");
scanf("%d",&len);

for(i=0; i<len; i++)
{
pBook pNew = (pBook)malloc(sizeof(Book));

printf("书名:");
scanf("%s",&pNew->Bdata.bookname);
printf("编号:");
scanf("%s",&pNew->Bdata.bookid);
printf("出版社:");
scanf("%s",&pNew->Bdata.publisher);
printf("价格:");
scanf("%f",&pNew->Bdata.price);
printf("上架日期: ");
scanf("%s",&pNew->Bdata.adddate);
printf("下架日期: ");
scanf("%s",&pNew->Bdata.outdate);
printf("来源: ");
scanf("%d",&pNew->Bdata.source);
printf("去向: ");
scanf("%d",&pNew->Bdata.direction);
printf("种类: ");
scanf("%d",&pNew->Bdata.kind);
printf("库存: ");
scanf("%d",&pNew->Bdata.num);

pTail->pNext = pNew;
pNew->pNext = NULL;
pTail = pNew;
printf("-------------------分割线-------------------\n");
}
return pHead;
}

pBook del(pBook pHead)
{
pBook elem = pHead; //用于索引的指针
pBook temp = NULL; //用于记录删除结点的上一个结点

char i[100];
printf("请输入需要检索的书名:");
scanf("%s",&i);

if (strcmp(i,elem->Bdata.bookname)== 0) //删除的正好是第一个结点
{
pHead = elem->pNext;
free(elem);
}
else
{
while (elem != NULL) //没有到尽头
{
temp = elem; //记录保存好
elem = elem->pNext; //往后索引

if (elem == NULL) //遍历完也没找到
{
printf("已搜索至末尾!\n");
}
else if(strcmp(i,elem->Bdata.bookname)== 0) //找到
{
temp->pNext = elem->pNext; //删除结点的前一个结点指向删除结点的后一个结点
free(elem); //释放删除结点的内存
break;
}
else
{
printf("没有找到要删除的结点\n");
}

}
}

return pHead;

}

pBook searchKind(pBook pHead)
{
char i[100];
pBook r = pHead;
printf("请输入需要检索的书名:");
scanf("%s",&i);
while(r != NULL)
{
if(strcmp(i,r->Bdata.bookid)== 0)
{
printf("搜索成功!\n");
printf("输入需要修改的书籍类型:");
scanf("%d",&r->Bdata.kind);
printf("书籍类型修改完成!\n");
}
r = r->pNext;
}
printf("筛选失败,没有符合的书籍!\n");
return 0;
}

pBook searchName(pBook pHead)
{
char i[100];
pBook r = pHead;
printf("请输入需要检索的书名:");
scanf("%s",&i);

while(r != NULL)
{
if(strcmp(i,r->Bdata.bookname)== 0)
{
printf("书籍搜索结果如下:\n");
singleoutput(r);
}
r = r->pNext;
}
printf("筛选失败,没有符合的书籍!\n");
return 0;
}

pBook searchName1(pBook pHead)
{
char i[100];
pBook r = pHead;
printf("请输入需要检索的书名:");
scanf("%s",&i);

while(r != NULL)
{
if(strcmp(i,r->Bdata.bookname)== 0)
{
printf("搜索成功!\n");
printf("输入需要修改的书籍名称:");
scanf("%s",&r->Bdata.bookname);
printf("书籍名称修改完成!\n");
}
r = r->pNext;
}
printf("筛选失败,没有符合的书籍!\n");
return 0;
}

pBook searchID(pBook pHead)
{
char i[100];
pBook r = pHead;
printf("请输入需要检索的序号:");
scanf("%s",&i);
while(r != NULL)
{
if(strcmp(i,r->Bdata.bookid)== 0)
{
printf("书籍搜索结果如下:\n");
singleoutput(r);
}
r = r->pNext;
}
printf("筛选失败,没有符合的书籍!\n");
return 0;
}

pBook searchID1(pBook pHead)
{
char i[100];
pBook r = pHead;
printf("请输入需要检索的序号:");
scanf("%s",&i);
while(r != NULL)
{
if(strcmp(i,r->Bdata.bookid)== 0)
{
printf("搜索成功!\n");
printf("输入需要修改的书籍编号:");
scanf("%s",&r->Bdata.bookid);
printf("书籍序号修改完成!\n");
}
r = r->pNext;
}
printf("筛选失败,没有符合的书籍!\n");
return 0;
}

void namesort(pBook pHead)
{
printf("开始执行排序函数\n");
pBook end;
struct bookdata t;
pBook p, pre;
p = pHead;
//end~NULL为有序部分,将end置为尾结点
while(p->pNext)
p = p->pNext;
end = p;
//每轮冒泡end左移一个结点,一直到head与end重合
while(pHead != end)
{
p=pHead;
while(p != end)
{
if(strcmp(p->Bdata.bookname,p->pNext->Bdata.bookname)>0)
{
t = p->Bdata;
p->Bdata = p->pNext->Bdata;
p->pNext->Bdata = t;
}
pre = p;
p = p->pNext;
}
end = pre;
}
printf("排序函数执行完毕.\n");
}

void output(pBook pHead)
{
pBook p = pHead->pNext;

while(p != 0)
{
printf("书名:");
printf("%s\n",p->Bdata.bookname);
printf("编号:");
printf("%s\n",p->Bdata.bookid);
printf("出版社:");
printf("%s\n",p->Bdata.publisher);
printf("价格:");
printf("%f\n",p->Bdata.price);
printf("上架日期:");
printf("%s\n",p->Bdata.adddate);
printf("下架日期:");
printf("%s\n",p->Bdata.outdate);
printf("来源:");
printf("%d\n",p->Bdata.source);
printf("去向:");
printf("%d\n",p->Bdata.direction);
printf("种类:");
printf("%d\n",p->Bdata.kind);
printf("库存数量:");
printf("%d\n",p->Bdata.num);

p=p->pNext;
printf("\n");
}
}

void singleoutput(pBook pHead)
{
pBook p = pHead;
printf("书名:");
printf("%s\n",p->Bdata.bookname);
printf("编号:");
printf("%s\n",p->Bdata.bookid);
printf("出版社:");
printf("%s\n",p->Bdata.publisher);
printf("价格:");
printf("%f\n",p->Bdata.price);
printf("上架日期:");
printf("%s\n",p->Bdata.adddate);
printf("下架日期:");
printf("%s\n",p->Bdata.outdate);
printf("来源:");
printf("%d\n",p->Bdata.source);
printf("去向:");
printf("%d\n",p->Bdata.direction);
printf("种类:");
printf("%d\n",p->Bdata.kind);
printf("库存数量:");
printf("%d\n",p->Bdata.num);
printf("\n");
}

pBook CreateList()
{
pBook pTail,pHead,q; //p指针总是指向新申请的结点;q指针总是指向尾节点
FILE *fp;
Book temp;
pTail=(pBook)malloc(sizeof(Book)); // p指向新开辟的节点内存
pHead = pTail;
q = pTail;
q->pNext = NULL;
fp=fopen("myBookcase421.txt","r");
while(fread(&temp,sizeof(Book),1,fp)!=0)
{
pTail=(pBook)malloc(sizeof(Book));
strcpy(pTail->Bdata.bookname,temp.Bdata.bookname);
strcpy(pTail->Bdata.bookid,temp.Bdata.bookid);
strcpy(pTail->Bdata.publisher,temp.Bdata.publisher);
pTail->Bdata.price = temp.Bdata.price;
strcpy(pTail->Bdata.adddate,temp.Bdata.adddate);
strcpy(pTail->Bdata.outdate,temp.Bdata.outdate);
pTail->Bdata.source = temp.Bdata.source;
pTail->Bdata.direction = temp.Bdata.direction;
pTail->Bdata.kind = temp.Bdata.kind;
pTail->Bdata.num = temp.Bdata.num;
q->pNext=pTail; //把新节点挂到原尾节点之后
q=q->pNext; //q指针指向新的尾节点
}
q->pNext=NULL;
fclose(fp);
return pHead;
}

void save(pBook pHead)
{
FILE *fp;
pBook p;
int count = 0,flag = 1;
fp = fopen("myBookcase421.txt","a+");
if(fp == NULL)
{
printf("该文件无法打开.\n");
}
p = pHead->pNext;

while(p)
{
if(fwrite(p,sizeof(Book),1,fp)==1) //注:这个文件输出为不可读写的格式
{
p = p->pNext;
count++;
}
else
{
flag=0;
break;
}
}
if(flag)
{
printf("\n保存数目为: %d\n",count);
}
fclose(fp);
}
...全文
164 点赞 收藏 6
写回复
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Orisland 2019-06-24
引用 5 楼 赵4老师 的回复:
数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

好的,我去看看,看来需要换换程序了啊。
回复
Orisland 2019-06-24
引用 4 楼 636f6c696e 的回复:
等于结构体又不代表拷贝,请改成memcpy

if(strcmp(p->Bdata.bookname,p->pNext->Bdata.bookname)>0)
{
//t = p->Bdata;
//p->Bdata = p->pNext->Bdata;
//p->pNext->Bdata = t;
memcpy(t, p->Bdata);
...
}
行,这个我改改……但是我这么写不会错啊,确实互换了啊……
回复
赵4老师 2019-06-24
数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633
回复
636f6c696e 2019-06-24
等于结构体又不代表拷贝,请改成memcpy

 if(strcmp(p->Bdata.bookname,p->pNext->Bdata.bookname)>0)
            {
                //t = p->Bdata;
                //p->Bdata = p->pNext->Bdata;
                //p->pNext->Bdata = t;
                memcpy(t, p->Bdata);
                ...
            }
回复
Orisland 2019-06-23
100查看0回复可太真实了……
回复
Orisland 2019-06-21
说明一下main函数里的几个调用函数是干嘛的:
pBook pHead = NULL;
pHead = CreateList(); //这个把文件中的链表数据读入程序
printf("从文件中读取完毕\n");
//add(pHead); //新增指定数量的书籍到链表
//output(pHead); //输出当前链表数据
//save(pHead); //保存链表数据到myBookcase421.txt文件
//del(pHead); //这个用不到,这是删除链表指定节点的
output(pHead);
namesort(pHead); //--------问题函数---------排序函数,主要看这里
output(pHead);

求大佬赏脸康康到底哪出错了
回复
Orisland 2019-06-21
这里是里面含有十个数据的txt读取文件,嫌自己输入麻烦可以直接在这里下载,放在代码目录下即可。
可以先//save和sort,先把output的//去掉,输出一次确认一下,第五个是大物。

该文件无法使用txt打开,只能用代码的这个程序打开。
链接:https://pan.baidu.com/s/1184xet3XnrulN-5_YsR0Rw
提取码:f3xd
回复
相关推荐
发帖
新手乐园
创建于2007-09-28

3.3w+

社区成员

C/C++ 新手乐园
申请成为版主
帖子事件
创建了帖子
2019-06-21 10:10
社区公告
暂无公告