求各位大神帮我修改一下本图书管理系统的BUG,本人万分感谢

ghxujei 2017-06-24 01:32:14
本人是个初学者。我们小组做完这个系统之后,还发现了几处BUG。其中多数都是在从键盘输入的是错误的数据。比如添加书的数量不写数字,故意写成英文,它不会报错,还会出错。我想请各位大神帮我看一下,这部分的BUG如何写入这段代码?已知的方法是使用ASC码,但是我不会转换……而且,我们连改都不知道从哪儿改。所以恳请大神帮帮忙,谢谢大神们啦!
// Library Manager.cpp : 定义控制台应用程序的入口点。
//

#include"stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{
int num;//书号
char title[50];//书名
char author[50];//著作者
int num1;//现存量
int num2;//库存量
char name[50];//借阅者姓名
int idnum;//学生证号

struct node *link;
}linklist;

linklist* creatnull(linklist *l)//申请单链表的空间
{
l=(linklist*)malloc(sizeof(linklist));//申请空间
l->link=NULL;//尾结点置空
return l;
}
void creat(linklist *l)//采编入库
{
int i,n;
linklist *p,*tail,*q;
tail=l;
if(l->link!=NULL)//判断:下一结点不为空
q=l->link;//q指针指向下一个结点
else q=l;//输入数据读入
while(tail->link!=NULL)
{
tail=tail->link;
};
printf("\n请输入入库图书的数量:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
p=(linklist*)malloc(sizeof(linklist));
printf("\n请输入入库图书的书号:");
scanf("%d",&p->num);
while(q->num!=p->num&&q->link!=NULL)//输入的书名重复
{
q=q->link;
}
if(q->num==p->num)
{
q->num1=q->num1+1;
q->num2=q->num2+1;
printf("\n该图书已在图书库存在,已自动增加图书数量");}
else
{
printf("\n请输入入库图书的书名:");
scanf("%s",&p->title);//传入数据至单链表数据域
printf("\n请输入入库图书的著作者:");
scanf("%s",&p->author);
printf("\n请输入入库图书的现存量:");
scanf("%d",&p->num1);
printf("\n请输入入库图书的库存量:");
scanf("%d",&p->num2);
strcpy(p->name,"NULL");
tail->link=p;
tail=p;
tail->link=NULL;//尾结点置空

};
}

}
void print(linklist *l)//输出所有图书的信息
{
linklist *p;
p=l->link;
printf("\n输出所有图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
while(p)//单链表没读完
{
printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
p=p->link;
}
}

void locat(linklist *l,int i)//根据书号查找图书 i是输入的书号
{
int count=0;
linklist *p;
p=l->link;
while(p->link!=NULL)
{
if(p->num!=i)
{
p=p->link;//下移一个结点
}
else
{
printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
p=p->link;
count++; //同书号的有多少个
}
};
if(p->num==i)
{
printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
count++;
}
if(count==0)
printf("该图书不在此书库!");
}

void locat1(linklist *l,int j)//根据学号查询
{
int count=0;
linklist *p;
p=l->link;
while(p->link!=NULL)
{
if(p->idnum!=j)
{
p=p->link;
}
else
{
printf("\n输出学生的信息:\n学号\t借阅者姓名\t书号\t书名\t著作者");
printf("\n%d\t%s\t\t%d\t%s\t%s\n",p->idnum,p->name,p->num,p->title,p->author);
p=p->link;
count++;
}
};
if(p->idnum==j)
{
printf("\n输出学生的信息:\n学号\t借阅者姓名\t书号\t书名\t著作者");
printf("\n%d\t%s\t\t%d\t%s\t%s\n",p->idnum,p->name,p->num,p->title,p->author);
p=p->link;
count++;
}
if(count==0)
printf("该学生未借阅!");
}

void borrowbook(linklist *l)//借阅
{
linklist *p;
int i;
int count=0;
printf("\n借阅的图书书号:");
scanf("%d",&i);
p=l->link;

while(p->link!=NULL)
{
if(p->num!=i)
{
p=p->link;
}
else
{
printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
p=p->link;
count++;
}
};
if(p->num==i)
{
printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
count++;
}
if(count==0)
{
printf("该图书不在此书库!");
}
else
{
if(p->num1<=0)
{
printf("\n该书库存不足,读者无法借阅.");
}
else
{
p->num1=p->num1-1;
printf("\n请输入借阅者的姓名:");
scanf("%s",&p->name);
printf("\n请输入借阅者的学生证号:");
scanf("%d",&p->idnum);
printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量\t借阅者姓名\t学生证号");
printf("\n%d\t%s\t%s\t%d\t%d\t%s\t\t%d\n",p->num,p->title,p->author,p->num1,p->num2,p->name,p->idnum);
}
}
}

void returnbook(linklist *l)//归还
{
linklist *p;int i,a;
int count=0;
int counta=0;
printf("\n请输入归还图书的书号:");
scanf("%d",&i);
p=l->link;

while(p->link!=NULL)
{
if(p->num!=i){p=p->link;}
else
{
p=p->link;
count++;
}
};
if(p->num==i){count++;}
if(count==0)
{
printf("该图书不在此书库!");
}
else
{
printf("\n请输入学生证号:");
scanf("%d",&a);
p=l->link;
while(p->link!=NULL)
{
if(p->idnum!=a){p=p->link;}
else
{
p=p->link;
counta++;
}
};
if(p->idnum==a){counta++;}
if(counta==0)
{
printf("该学生未借阅图书!");
}
else
{
p->num1=p->num1+1;
strcpy(p->name,"NULL");
printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
}
}
}
int main()
{
linklist l,*head;//初始化单链表头结点
head=creatnull(&l);
printf(" *********************************\n");
printf(" 欢迎使用图书管理系统 \n");
printf(" *********************************\n");
printf("\n");
int flag=1,a;
while(flag)
{
printf(" *************************************\n");
printf(" 1:馆藏图书信息 \n");
printf(" 2:采编入库 \n");
printf(" 3:图书查询 \n");
printf(" 4:学号查询 \n");
printf(" 5:读者借阅 \n");
printf(" 6:读者归还 \n");
printf(" 7:退出图书管理系统 \n");
printf(" *************************************\n");
printf(" 请输入您的选项:");
scanf("%d",&a);
switch(a)
{

case 7:flag=0;
printf(" *********************************\n");
printf(" 成功退出图书管理系统 \n");
printf(" *********************************\n");
break;
case 1:flag=1;
print(head);
printf("\n\n\n");
break;
case 2:flag=1;
creat(head);
printf("\n\n\n");
break;
case 3:flag=1;
int number;//书号
printf("\n请输入要查找的图书书号:");
scanf("%d",&number);
locat(head,number);
printf("\n\n\n");
break;
case 4:flag=1;
int idnumber;//学号
printf("\n请输入要查找的学号:");
scanf("%d",&idnumber);
locat1(head,idnumber);
printf("\n\n\n");
break;
case 5:
flag=1;


borrowbook(head);
printf("\n\n\n");
break;
case 6:flag=1;
returnbook(head);
printf("\n\n\n");
break;
}
}
system("pause");
return 1;
}

...全文
259 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ghxujei 2017-06-27
  • 打赏
  • 举报
回复
感谢各位帮助了。我改一下试试看。意见好多啊,不过我也受教了。蟹蟹!
赵4老师 2017-06-26
  • 打赏
  • 举报
回复
printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方,而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。 在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。
//请今后要用
char c;
scanf("%c",&c);
//时,都改为
char s[2];
char c;
scanf("%1s",s);
c=s[0];
“多一少一”问题占程序员常犯错误的10%以上! 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断,掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个? <、<=、==、>、>=中的哪个?
自信男孩 2017-06-26
  • 打赏
  • 举报
回复
//#include"stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct node
{
    int num;//书号
    char title[50];//书名
    char author[50];//著作者
    int num1;//现存量
    int num2;//库存量
    char name[50];//借阅者姓名
    int idnum;//学生证号
    struct node *link;
}linklist;

linklist* creatnull(linklist *l)//申请单链表的空间
{
    l = (linklist*)malloc(sizeof(linklist));//申请空间
    l->link = NULL;//尾结点置空
    return l;
}
void creat(linklist **l)//采编入库
{
    int i,n;
    linklist *p,*tail,*q;
    tail = *l;
    if((*l)->link!=NULL)//判断:下一结点不为空
        q= (*l)->link;//q指针指向下一个结点
    else q = *l;//输入数据读入
    while(tail->link!=NULL)
    {
        tail=tail->link;
    };
    printf("\n请输入入库图书的数量:");
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        p=(linklist*)malloc(sizeof(linklist));
        printf("\n请输入入库图书的书号:");
        scanf("%d",&p->num);
        while(q->num!=p->num&&q->link!=NULL)//输入的书名重复
        {
            q=q->link;
        }
        if(q->num==p->num)
        {
            q->num1=q->num1+1;
            q->num2=q->num2+1;
            printf("\n该图书已在图书库存在,已自动增加图书数量");}
        else
        {
            printf("\n请输入入库图书的书名:");
            scanf("%s", p->title);//传入数据至单链表数据域
            printf("\n请输入入库图书的著作者:");
            scanf("%s", p->author);
            printf("\n请输入入库图书的现存量:");
            scanf("%d",&p->num1);
            printf("\n请输入入库图书的库存量:");
            scanf("%d",&p->num2);
            strcpy(p->name,"NULL");
            tail->link=p;
            tail=p;
            tail->link=NULL;//尾结点置空

        };
    }

}
void print(linklist *l)//输出所有图书的信息
{
    linklist *p;
    p=l->link;
    printf("\n输出所有图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
    while(p)//单链表没读完
    {
        printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
        p=p->link;
    }
}

void locat(linklist *l,int i)//根据书号查找图书    i是输入的书号
{
    int count=0;
    linklist *p;
    p=l->link;
    while(p->link!=NULL)
    {
        if(p->num!=i)
        {
            p=p->link;//下移一个结点
        }
        else
        {
            printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
            printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
            p=p->link;
            count++;   //同书号的有多少个
        }
    };
    if(p->num==i)
    {
        printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
        printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
        count++;
    }
    if(count==0)
        printf("该图书不在此书库!");
}

void locat1(linklist *l,int j)//根据学号查询
{
    int count=0;
    linklist *p;
    p=l->link;
    while(p->link!=NULL)
    {
        if(p->idnum!=j)
        {
            p=p->link;
        }
        else
        {
            printf("\n输出学生的信息:\n学号\t借阅者姓名\t书号\t书名\t著作者");
            printf("\n%d\t%s\t\t%d\t%s\t%s\n",p->idnum,p->name,p->num,p->title,p->author);
            p=p->link;
            count++;
        }
    };
    if(p->idnum==j)
    {
        printf("\n输出学生的信息:\n学号\t借阅者姓名\t书号\t书名\t著作者");
        printf("\n%d\t%s\t\t%d\t%s\t%s\n",p->idnum,p->name,p->num,p->title,p->author);
        p=p->link;
        count++;
    }
    if(count==0)
        printf("该学生未借阅!");
}

void borrowbook(linklist *l)//借阅
{
    linklist *p;
    int i;
    int count=0;
    printf("\n借阅的图书书号:");
    scanf("%d", &i);
    p = l->link;

    printf("bookno = %d\n", i);
    while(p != NULL)
    {
        if(p->num != i)
        {
            p=p->link;
        }
        else
        {
            printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
            printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
            //p = p->link;
            break;
            count++;
        }
    }
    if(p != NULL && p->num == i)
    {
        printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
        printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
        count++;
    }
    if(count == 0)
    {
        printf("该图书不在此书库!");
    }
    else
    {
        if(p->num1<=0)
        {
            printf("\n该书库存不足,读者无法借阅.");
        }
        else
        {
            p->num1=p->num1-1;
            printf("\n请输入借阅者的姓名:");
            scanf("%s", p->name);
            printf("\n请输入借阅者的学生证号:");
            scanf("%d",&p->idnum);
            printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量\t借阅者姓名\t学生证号");
            printf("\n%d\t%s\t%s\t%d\t%d\t%s\t\t%d\n",p->num,p->title,p->author,p->num1,p->num2,p->name,p->idnum);
        }
    }
}

void returnbook(linklist *l)//归还
{
    linklist *p;int i,a;
    int count=0;
    int counta=0;
    printf("\n请输入归还图书的书号:");
    scanf("%d",&i);
    p = l->link;

    while(p != NULL)
    {
        if(p->num!=i){p=p->link;}
        else
        {
            break;
        }
    };
    if(p->num==i){
        count++;
    }
    if(count==0)
    {
        printf("该图书不在此书库!");
    }
    else
    {
        printf("\n请输入学生证号:");
        scanf("%d",&a);
        p = l->link;
        while(p)
        {
            if(p->idnum!=a){
                p=p->link;
            }
            else
            {
                break;
            }
        }
        if(p && p->idnum==a) {
            counta++;
        }
        if(counta==0)
        {
            printf("该学生未借阅图书!");
        }
        else
        {
            p->num1=p->num1+1;
            strcpy(p->name,"NULL");
            printf("\n输出图书的信息:\n书号\t书名\t著作者\t现存量\t库存量");
            printf("\n%d\t%s\t%s\t%d\t%d\n",p->num,p->title,p->author,p->num1,p->num2);
        }
    }
}
int main()
{
    linklist l,*head;//初始化单链表头结点
    head=creatnull(&l);
    printf("                 *********************************\n");
    printf("                       欢迎使用图书管理系统       \n");
    printf("                 *********************************\n");
    printf("\n");
    int flag=1,a;
    while(flag)
    {
        printf("               *************************************\n");
        printf("                          1:馆藏图书信息            \n");
        printf("                          2:采编入库                \n");
        printf("                          3:图书查询                \n");
        printf("                          4:学号查询                \n");
        printf("                          5:读者借阅                \n");
        printf("                          6:读者归还                \n");
        printf("                          7:退出图书管理系统        \n");
        printf("               *************************************\n");
        printf("                            请输入您的选项:");
        scanf("%d",&a);
        switch(a)
        {

            case 7:flag=0;
                   printf("                 *********************************\n");
                   printf("                       成功退出图书管理系统       \n");
                   printf("                 *********************************\n");
                   break;
            case 1:flag=1;
                   print(head);
                   printf("\n\n\n");
                   break;
            case 2:flag=1;
                   creat(&head);
                   printf("\n\n\n");
                   break;
            case 3:flag=1;
                   int number;//书号
                   printf("\n请输入要查找的图书书号:");
                   scanf("%d",&number);
                   locat(head,number);
                   printf("\n\n\n");
                   break;
            case 4:flag=1;
                   int idnumber;//学号
                   printf("\n请输入要查找的学号:");
                   scanf("%d",&idnumber);
                   locat1(head,idnumber);
                   printf("\n\n\n");
                   break;
            case 5:
                   flag=1;


                   borrowbook(head);
                   printf("\n\n\n");
                   break;
            case 6:flag=1;
                   returnbook(head);
                   printf("\n\n\n");
                   break;
        }
    }
    system("pause");
    return 1;
}
除了scanf处输入有若干错误;主要是scanf以%s输入时,不需要加前面的&,因为数组名本身就是地址。 借书和还书还有问题,逻辑上还存在问题。链表遍历时,不能遍历到最后一个节点,所以改成while (p)形式判断。另外,若找到节点,不应该再执行p = p->link,而是直接跳出循环。 以上改动,详见代码!
BlueDamage 2017-06-25
  • 打赏
  • 举报
回复
示例(部分代码) printf(" 21点\n"); printf("1.开始游戏\n"); printf("2.操作设置\n"); printf("3.难度设置\n"); printf("4.查看排名\n"); printf("5.操作帮助\n"); printf("6.退出游戏\n"); printf("\n选择菜单: "); scanf("%d",&menu); while( menu<=0 || menu>=7) { if(menu<-10000) { getchar(); printf("\n好端端的,干嘛输入字母!\n"); printf("请重新选择菜单: "); scanf("%d",&menu); }else { printf("\n菜单选择错误!\n请重新选择菜单: "); scanf("%d",&menu); } } 这里解释下,我在这里判断menu的值看是否输入了字母.因为定义menu时,没给值,它会随机地被赋予一个很大的负数. 通过判断不是很大的负数默认来确定有没有成功地获取用户输入的数据. 但这方法不够""判断sanf返回值来确定有没有成功地获取用户输入的数据"好
BlueDamage 2017-06-25
  • 打赏
  • 举报
回复
引用 4 楼 ghxujei 的回复:
其实我也希望直接写一个函数,然后每次从键盘输入的时候都调用一下判定是否为数字,这样的话所有的地方就都不会出问题了。但是我确实是不会写。真的不知道从何入手。
可以这样实现,用%s读取用户输入的数据并存到数组str 然后遍历str,若存在0-9为外的字符,返回false
BlueDamage 2017-06-25
  • 打赏
  • 举报
回复
解决方法: 出错时,加条语句来清空缓冲区 方法一:scanf("%s", s); 方法二: scanf(“%*[^\n]%*c”): 出错原因: 用scanf("d",&n);只会从缓冲区获取数字,就是说,输入了字母的话,他就获取不了缓冲区的字符! 如果是循环获取的话,就永远卡死,因为scanf("d",&n);永远获取不到应有的数字. 所以,你该把字母读走然后再scanf("d",&n); 所以,你也可以用读把n声明为char类型,这样的话就不会出现这样的问题(要读取数字,却有字符阻拦着)了! 其次,你还可以通过sanf的返回值去判断,是否读到了字符,没有的话就用清空缓冲区 关于缓冲区的问题,你也可以看看我博客中初学c常见问题,里面有提到过缓冲区的
ghxujei 2017-06-25
  • 打赏
  • 举报
回复
其实我也希望直接写一个函数,然后每次从键盘输入的时候都调用一下判定是否为数字,这样的话所有的地方就都不会出问题了。但是我确实是不会写。真的不知道从何入手。
ghxujei 2017-06-25
  • 打赏
  • 举报
回复
是这样。

while(tail->link!=NULL)
    {
        tail=tail->link;
    };
    printf("\n请输入入库图书的数量:");
    scanf("%d",&n);
当我在提示之后输入字母,他会出错。我想在程序中加上一段代码,可以检测我输入的是否为数字,如果不是数字,就提示请正确输入数字,然后重新输入。如果是数字的话,才进行下一步。
动力风暴 2017-06-25
  • 打赏
  • 举报
回复
printf(" *************************************\n"); printf(" 1:馆藏图书信息 \n"); printf(" 2:采编入库 \n"); printf(" 3:图书查询 \n"); printf(" 4:学号查询 \n"); printf(" 5:读者借阅 \n"); printf(" 6:读者归还 \n"); printf(" 7:退出图书管理系统 \n"); printf(" *************************************\n"); printf(" 请输入您的选项:"); scanf("%d",&a); 这个要求程序属于一个数字,且要求是1-7,如果是其他数字或字符,程序就会进入死循环。
zhu_meng_ 2017-06-24
  • 打赏
  • 举报
回复
printf("\n请输入入库图书的现存量:");
scanf("%d",&p->num1);
printf("\n请输入入库图书的库存量:");
scanf("%d",&p->num2);

你是说的这两个吗?输入非数字的时候你们的程序还能运行?
如果是这里,把控制台输入当成字符串,读入字符串后判断字符串是不是全数字,不是全数字提示错误
信息,让用户重新输入,知道输入你们认为合法的值。
建议,应该用界面的方式进行录入。还有最后的书籍不应该保存在内存中。最好能用数据库保存。
以上建议仅供参考。

69,370

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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