为什么我的C++程序第一次运行正常,再次运行就有问题?
小弟用链表编一个c++图书管理系统,目前只包括新书入库和查书功能。
程序主要有两个问题,第一个问题是查书功能中采用书名或作者名查询时结果会出现两遍;第二个问题就是程序第一次运行正常,再次运行时添加书还可以,但查询时就会出错。
希望高手不吝赐教!
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
using namespace std;
class Book
{
public:
Book();
Book(string num,string aut,string tit,int stn=1,int otn=0);
Book* RemoveAfter();
friend class Booklist;
void display();
string number;
string author;
string title;
int storenum;
int outnum;
Book *next;
};
Book::Book(){next=NULL;}
Book::Book(string num,string aut,string tit,int stn,int otn){
number=num;
author=aut;
title=tit;
storenum=stn;
outnum=otn;
next=NULL;
}
void Book::display(){
cout < < "书目号: " < <number < <endl < < "作者: " < <author < <endl < < "书名: " < <title < <endl < < "库存册数: " < <storenum < <endl < < "已借出册书: " < <outnum < <endl;
}
Book* Book::RemoveAfter(){
Book* p=next;
if(next==NULL)p=NULL;
else next=p-> next;
return p;
}
class Booklist
{
public:
Booklist();
void PrintList();
void InsertRear(Book *p1);
Book* CreateBook(Book bk);
Book* DeleteBook(Book *p1);
void Find();
Book *head,*rear;
};
Booklist::Booklist(){
head=rear=new Book();
}
void Booklist::PrintList(){
Book *p=head-> next;
while(p!=NULL){
p-> display();
p=p-> next;
}
}
void Booklist::InsertRear(Book *p1){
p1-> next=rear-> next;
rear-> next=p1;
rear=p1;
}
Book* Booklist::CreateBook(Book bk)
{Book *p=new Book(bk);
return p;
}
Book* Booklist::DeleteBook(Book *p1)
{Book* p=head;
while(p-> next!=NULL&&p-> next!=p1)p=p-> next;
if(p-> next==rear)rear=p;
return p-> RemoveAfter();
}
void Booklist::Find(){
Book *p;
cout < < "1.按照书目编号查找 " < <endl < < "2.按照书名查找 " < <endl < < "3.按照作者名查找 " < <endl;
int i;
cin> > i;
string num,aut,tit;
switch(i){
case 1:cout < < "请输入书目编号: " < <endl;
cin> > num;
p=head-> next;
while(p!=NULL&&p-> number!=num)p=p-> next;
if(p==NULL){
cout < < "查找失败! ";
break;}
p-> display();
break;
case 2:cout < < "请输入书名: " < <endl;
cin> > tit;
p=head-> next;
while(p!=NULL&&p-> title!=tit)p=p-> next;
if(p==NULL){
cout < < "查找失败! ";
break;}
p-> display();p=p-> next;
while(p!=NULL){if(p-> title==tit)p-> display();
p=p-> next;}
break;
case 3:cout < < "请输入作者名: " < <endl;
cin> > aut;
p=head-> next;
while(p!=NULL&&p-> author!=aut)p=p-> next;
if(p==NULL){
cout < < "查找失败! ";
break;}
p-> display();p=p-> next;
while(p!=NULL){if(p-> author==aut)p-> display();
p=p-> next;}
break;
}
}
void Addbook();
void Findbook();
int main()
{
start:cout < <endl < <endl < < "图书管理系统 " < <endl < <endl < < "1.新书入库 " < <endl < < "2.图书查询 " < <endl < < "3.处理借书 " < <endl < < "4.处理还书 " < <endl < < "5.删除图书 " < <endl < < "6.输出全部图书信息和全部读者信息 " < <endl < < "7.增加和删除读者信息 " < <endl < < "0.退出 " < <endl;
int i;
cin> > i;
switch(i)
{case 1:Addbook();goto start;
case 2:Findbook();goto start;
case 3:;
case 4:;
case 5:;
case 6:;
case 0:return 0;
default:cout < < "输入错误,请重新输入1-6的数字操作 " < <endl;goto start;}
return 0;
}
void Addbook(){
string bt,au; //书名和作者名的变量
cout < < "请输入书名: " < <endl;
cin> > bt;
cout < < "请输入作者名: " < <endl;
cin> > au;
ifstream bfile( "Book.dat ",ios::in);
bfile.seekg(ios::beg);
if(!bfile)
{cerr < < "打开文件时发生错误! " < <endl;
abort();}
Booklist list1;
Book *P1;
Book a;
while(!bfile.eof()){
bfile.read((char*)&a,sizeof(a));
P1=list1.CreateBook(a);
list1.InsertRear(P1);
}
bfile.close();
Book *p=list1.head-> next;
while(p!=NULL)
{if(p-> title==bt&&p-> author==au){(p-> storenum)++;cout < <p-> title < < "数量添加一本 " < <endl;break;}
else p=p-> next;
}
if(p==NULL){
cout < < "该书原先馆内未存,请继续输入图书编号以完成信息添加: " < <endl;
string num;
cin> > num;
Book b(num,au,bt);
P1=list1.CreateBook(b);
list1.InsertRear(P1);
}
ofstream bfileo( "Book.dat ",ios::out|ios::trunc);
bfileo.seekp(ios::beg);
p=list1.head-> next;
while(p!=NULL)
{
bfileo.write((char*)&(*p),sizeof(*p));
p=p-> next;
}
bfileo.close();
}
void Findbook(){
ifstream bfile( "Book.dat ",ios::in);
bfile.seekg(ios::beg);
if(!bfile)
{cerr < < "打开文件时发生错误! " < <endl;
abort();}
Booklist list1;
Book *P1;
Book a;
while(!bfile.eof()){
bfile.read((char*)&a,sizeof(a));
P1=list1.CreateBook(a);
list1.InsertRear(P1);
}
bfile.close();
list1.Find();
}
[解决办法]
我以前也遇过,应该是读文件判断是否到尾部的时候,他会输出两次。
你判断读文件是否到尾部时,判断条件用是否为空的方法判断它是否到尾部。
这样应该不会错了。
[解决办法]
while(1)
{
if(!bfile.eof())
{
执行的正常代码.....
}
else break;
}