回 帖 发 新 帖 刷新版面

主题:控制台运行意外终止

这是我改过后的程序,编译没有错误了,但是每次运行时,比如你输入一组信息后,再选择列出所有信息这一栏。控制台都会意外终止。出现该内存不能为read的对话框。具体情况我已经截屏了,就在上传的文件中。
我请教了一位高人,他说c++本来就提供了链表库,我自己实现链表很容易出错。
类似于p1->next=NULL; p->next=p1;的语句。错误很有可能出在指针指向和return语句里。我从来没听过这样的问题,不知道改怎么办了。大家能给点建议吗?谢谢!最好不要改动源程序的主要框架。
//设备管理系统main.cpp
#include<fstream>
#include<iostream>
#include<string>
using namespace std;
struct mach_type
{
    int num;//设备编号
    string name;//名称
    int left;//库存数
    float price;//单价
    string factory;//生产厂家
    string provider;//供货商
    mach_type *next;
};
class Machine//定义Machine类
{
private:
    mach_type *head;//头指针
    void Print(mach_type *);//输出一条指定的记录
    mach_type *Find1(int);//查找符合条件的记录,并返回该记录的指针
    mach_type *Find2(string);
public:
    Machine(){head=NULL;}
    mach_type *get_head(){return head;}//获得头指针
    int Listcount();//统计记录总数,并返回一个整数
    void Additem(int num,string name,int left,float price,string factory, string provider);//添加一条记录到表尾
    void Removeitem(int);//删除一条制指定记录
    void List();//列出当前链表中的所有记录
    void Search1(int);//在当前链表通过设备编号查找
    void Search2(string);//在当前链表通过供货商查找
};
//类成员函数开始
int Machine::Listcount()//统计记录总数,并返回一个整数
{
    if(!head)return 0;
    mach_type *p=head;
    int n=0;
    while(p){n++;p=p->next;}
    return n;
}
void Machine::Additem(int num,string name,int left,float price,string factory, string provider)//添加一条记录到表尾
{
    if(!head)//如果头指针等于NULL
    {
        head=new mach_type;//将新增记录赋给头指针
        head->num=num;
        head->name=name;
        head->left=left;
        head->price=price;
        head->factory=factory;
        head->provider=provider;
    }
    mach_type *t=head;
    while(t && t->num!=num)t=t->next;//如果t不为NULL且t中的num不为查找的num,向下继续查找链表
    if(t){cout<<"请输入增加的库存数:"<<endl;t->left+=left;return;}
    else
    {
      mach_type *p=head;
      while(p->next)p=p->next;
      mach_type *p1=new mach_type;
      p1->num=num;
      p1->name=name;
      p1->left=left;
      p1->price=price;
      p1->factory=factory;
      p1->provider=provider;
      p1->next=NULL;
      p->next=p1;
      return;
    }
}
void Machine::Removeitem(int num)//删除指定编号设备的记录
{
    mach_type *t=Find1(num);
    if(!t)return;
    mach_type *p=head;
    //如果要删除的记录位于表头
    if(head==t){
        head=head->next;
        delete p;
        cout<<"成功删除编号为"<<num<<"的设备!"<<endl<<endl;
        return;
    }
    while(p->next!=t)p=p->next;
    mach_type *p1=p->next;
    p->next=p1->next;
    delete p1;
    cout<<"成功删除编号为"<<num<<"的设备!"<<endl<<endl;
    return;
}
void Machine::Print(mach_type *p)//输出一条指定的记录
{
    cout<<p->num<<"\t\t";
    cout<<p->name<<"\t\t";
    cout<<p->left<<"\t\t";
    cout<<p->price<<"\t\t";
    cout<<p->factory<<"\t\t";
    cout<<p->provider<<endl;
    return;
}
void Machine::List()//列出当前列表中的所有记录
{
    if(Listcount==0){cout<<"错误:当前的列表为空!";return;}
    mach_type *p=head;
    cout<<"共有记录:"<<Listcount()<<endl;
    cout<<"型号\t\t名称\t\t库存数\t\t单价\t\t生产厂家\t\t供货商"<<endl;
    while(p)
    {
        Print(p);
        p=p->next;
    }
        cout<<endl;
    return;
}
void Machine::Search1(int num)//在当前链表通过编号查找指定记录并输出
{
    cout<<"Searching..."<<endl;
    mach_type *p=Find1(num);
    if(p)
    {cout<<"型号\t\t名称\t\t库存数\t\t单价\t\t生产厂家\t\t供货商"<<endl;
        Print(p);}
    cout<<endl;
}
mach_type *Machine::Find1(int num)//返回指定编号的指针
{
    if(Listcount()==0){cout<<"错误:当前的列表为空!"<<endl;
    return NULL;
    }
    mach_type *p=head;
    while(p){
        if(p->num==num)break;
        p=p->next;}
    if(!p){cout<<"错误:找不到该记录!\n";
    return NULL;}
    return p;
}
void Machine::Search2(string name)//在当前链表通过名称查找指定记录并输出
{
    cout<<"Searching..."<<endl;
    mach_type *p=Find2(name);
    if(p)
    {cout<<"型号\t\t名称\t\t库存数\t\t单价\t\t生产厂家\t\t供货商"<<endl;
        Print(p);}
    cout<<endl;
}
mach_type *Machine::Find2(string name)//返回指定名称的指针
{
    if(Listcount()==0){cout<<"错误:当前列表为空!"<<endl;
    return NULL;}
    mach_type *p=head;
    while(p){if(p->name==name)break;p=p->next;}
    if(!p){cout<<"错误:找不到该记录!\n"<<endl;return NULL;}
    return p;
}
Machine machine;//定义全局变量
int Menu()
{
    cout<<"=======================主菜单======================="<<endl;
    int n=1,select=-1;
    cout<<n++<<".输入设备信息;"<<endl<<endl;
    cout<<n++<<".按设备编号查找记录;"<<endl<<endl;
    cout<<n++<<".按设备名称查找记录;"<<endl<<endl;
    cout<<n++<<".删除由编号制定的设备;"<<endl<<endl;
    cout<<n++<<".列出所有设备记录;"<<endl<<endl;
    cout<<n++<<".从数据文件导入设备信息;"<<endl<<endl;
    cout<<n++<<".将设备信息导出到磁盘文件;"<<endl<<endl;
    cin>>select;
    return select;
}
char Exit()
{
    char s;
    cout<<"确定要推出程序吗?[Y/N]:";
    cin>>s;
    return s;
}
void Input(int *num,string *name,int *left,float *price,string *factory,string *provider)//输入学生信息
{
    cout<<"请输入  编号  名称  库存数  单价  生产厂家  供货商:"<<endl;
    cin>>*num;
    if(*num==-1)return;
    cin>>*name>>*left>>*price>>*factory>>*provider;
return;
}
void Addnew()
{
    int num=0,left=0;
    float price=0;
    string name=" ";string factory=" ";string provider=" ";
    cout<<endl<<"当输入的编号为-1时表示结束输入。"<<endl;
    Input(&num,&name,&left,&price,&factory,&provider);
    while(num!=-1)
    {
        machine.Additem(num,name,left,price,factory,provider);
        Input(&num,&name,&left,&price,&factory,&provider);
    }
return;
}
void Dofind1()
{
    int num;
    cout<<"当输入的编号为-1时表示结束输入。"<<endl;
    do{
        cout<<"请输入要查找设备的编号:";
        cin>>num;
        if(num==-1)continue;
        machine.Search1(num);
    }while(num!=-1);
    return;
}
void Dofind2()
{
    string name;
    cout<<"当输入的名称为-1时表示结束输入"<<endl;
    do{
        cout<<"请输入要查找的设备名称:"<<endl;
        cin>>name;
        if(name=="-1")continue;
        machine.Search2(name);
    }while(name!="-1");
    return;
}
void Dodelete()
{
    cout<<endl<<"当输入的编号为-1时表示结束"<<endl;
    int num;
    do{
        cout<<"请输入要删除设备的编号:"<<endl;
        cin>>num;
        if(num==-1)continue;
        machine.Removeitem(num);
    }while(num!=-1);
    return;
}
void List(){machine.List();}
void Loadfromfile()
{
    int num,left;float price;char name[20]="";char factory[20]="";char provider[20]="";
    fstream iofile;
    int i=0;
    iofile.open("machine.dat",ios::in|ios::binary);
    if(!iofile){
        cout<<"数据文件不存在,请先建立该文件"<<endl;
        return;
    }
    if(iofile.eof())
    {

        cout<<"数据库为空,请添加数据"<<endl;
        iofile.close();
    }
    else
    {
        while(iofile.peek()!=EOF)
        {
            iofile.read((char *) &num,sizeof(int));
            iofile.read((char *) name,20);
            iofile.read((char *) &left,sizeof(int));
            iofile.read((char *) &price,sizeof(float));
            iofile.read((char *) factory,20);
            iofile.read((char *) provider,20);
            machine.Additem(num,name,left,price,factory,provider);
        }
        iofile.close();
    }
}
void Savetofile()
{
    mach_type *p;
    char name[20];char factory[20];char provider[20];
    fstream iofile;
    int i=0;
    iofile.open("machine.dat",ios::out|ios::binary);
    if(!iofile){
        cerr<<"open error!"<<endl;
        abort();
    }
    p=machine.get_head();
    while(p)
    {
        p->name.copy(name,20,0);
        name[p->name.length()]=0;
        iofile.write((char *) &p->num,sizeof(int));
        iofile.write((char *) name,20);
        iofile.write((char *) &p->left,sizeof(int));
        iofile.write((char *) &p->price,sizeof(float));
        iofile.write((char *) factory,20);
        iofile.write((char *) provider,20);
        p=p->next;
    }
    iofile.close();
}
int main()
{
    cout<<"Welcome!\n设备管理系统\nVer 1.01\n \n\n";
    int select;
    char s;
    while(1)
    {
        select=Menu();
        switch(select)
        {
          case 0:
             s=Exit();
             if(s=='y'||s=='Y')return 0;
             break;
          case 1:
             Addnew();
             break;
          case 2:
             Dofind1();
             break;
          case 3:
             Dofind2();
             break;
          case 4:
             Dodelete();
             break;
          case 5:
             List();
             break;
          case 6:
             Loadfromfile();
             break;
          case 7:
             Savetofile();
             break;
          default:
             cout<<"无效输入!"<<endl;
        }
    }
return 0;
}


回复列表 (共4个回复)

沙发

有点晕,你把代码拆得碎过头了……
想了想,问题有可能是出在这一段
    if(!head)//如果头指针等于NULL
    {
        head=new mach_type;//将新增记录赋给头指针
        head->num=num;
        head->name=name;
        head->left=left;
        head->price=price;
        head->factory=factory;
        head->provider=provider;
    }
这里直接写上head->next=NULL;和return,然后再测一下试试?

板凳

void Machine::List()//列出当前列表中的所有记录
{
    if(Listcount==0){cout<<"错误:当前的列表为空!";return;}//应该是Listcount()吧?你怎么通过编译的??
    mach_type *p=head;
    cout<<"共有记录:"<<Listcount()<<endl;
    cout<<"型号\t\t名称\t\t库存数\t\t单价\t\t生产厂家\t\t供货商"<<endl;
    while(p)
    {
        Print(p);
        p=p->next;
    }
        cout<<endl;
    return;
}

3 楼

改正上述错误之后我用dev c++调试通过
lz建议你查查你的输入

4 楼

从你的图片可以看出 输出searching后出现异常
那就去找search函数
从search查找发现没有对内存写的操作除了mach_type *p=Find1(num)
所以去找Find1()函数 函数中有个操作是p=p->next  是不是p->next有问题?
所以去查下构造函数 
链表的构造只有一个Additem
发现
[code=c]

if(!head)//如果头指针等于NULL
    {
        head=new mach_type;//将新增记录赋给头指针
        head->num=num;
        head->name=name;
        head->left=left;
        head->price=price;
        head->factory=factory;
        head->provider=provider;
        //head->next=NULL; 少这一句 head->next不确定
    }

[/code]

我来回复

您尚未登录,请登录后再回复。点此登录或注册