| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 695 人关注过本帖
标题:visual。猥琐。纠结人的bug。求救。。。关于电话本,在删除一个成员的时候, ...
只看楼主 加入收藏
fishviv
Rank: 1
等 级:新手上路
帖 子:45
专家分:9
注 册:2010-9-10
结帖率:90.91%
收藏
已结贴  问题点数:17 回复次数:3 
visual。猥琐。纠结人的bug。求救。。。关于电话本,在删除一个成员的时候,delete有问题,加*的地方,但是放在dev就没有问题。
   
程序代码:
#include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdlib>
using namespace std;

typedef struct call{
    char name[20];
    char telenum[12];
    struct call*nextPtr;
}call;//链表包括 成员的名字和电话号码,还有指针
call*deletePtr;//用于存储要被删除成员的位置
call*solPtr=NULL;//表示要插入的位置
call*startPtr=NULL;//链表开始的位置
class telephone//每一个成员的对象
{  public:
      telephone(){}//构造函数
      void add(telephone &tel);//每一个对象都可以添加到电话本中
      void set1(char ch[20],telephone &tel);//每一个对象都需要有姓名
      void set2(char ch1[12],telephone &tel);//每一个对象都需要有号码
      void delete_num(call*p1);//每一个对象都可以被删除
      call* research(telephone &tel);//每一个对象都可以被查找
      void change(call*p);//每一个对象都可以被重新编辑
      ~telephone(){}
   private:
      char Pname[20];
      char  Ptelenum[12];//电话本的每一个对象都必须有名字和号码
};
void telephone::add(telephone& tel)//把一个对象添加到电话本中,通过引用传值,为了调用对象的私有成员
{    call* currentPtr=NULL;//当前处理的一个指针
    call* newPtr=new call;//有new动态申请一个指向
    call*pptr;//用于打印时候的的指针,防止全局变量被改变
    int i;
    for(i=0;i<20;i++)
            newPtr->name[i]='\0';
    for(i=0;i<20;i++)
            newPtr->telenum[i]='\0';
      for(i=0;i<20;i++)
        newPtr->name[i]=tel.Pname[i];
      for(i=0;i<12;i++)
         newPtr->telenum[i]=tel.Ptelenum[i];//把类里面的私有成员赋值给链表中的
      if(startPtr!=NULL)//如果添加的对象不是第一个
      {    if(solPtr==startPtr)//如果要插入的位置是在链表开始的位置的前后
        {   for(i=0;i<20;i++)
                if((startPtr->name[i]-'a')!=(newPtr->name[i]-'a'))
                   break;//再次比较在第几个字符的地方,新添的对象与开始的位置不同
            if((startPtr->name[i]-'a')>(newPtr->name[i]-'a'))//
            {    currentPtr=startPtr;
                startPtr=newPtr;
                startPtr->nextPtr=currentPtr;//在链表的开始插入对象,重新定义链表头
            }
            else//如果在开始位置后面插入就与平时的链表的插入相似
            {    currentPtr=solPtr->nextPtr;
                solPtr->nextPtr=newPtr;
                newPtr->nextPtr=currentPtr;
            }
        }
        else
        {      currentPtr=solPtr->nextPtr;//如果不是在链表开始位置的前后.链表的插入工作
            solPtr->nextPtr=newPtr;
            newPtr->nextPtr=currentPtr;
        }
      }
      else                                  
      { startPtr=newPtr;
        startPtr->nextPtr=NULL;//如果是第一次开始的链表的插入
      }
     cout<<"增加成功"<<endl;
     pptr=startPtr;//从头开始打印
     while(pptr!=NULL)
     {cout<<pptr->name<<"->";
      pptr=pptr->nextPtr;
     }
}
void telephone::delete_num(call*p1)//删除链表
{    call* currentPtr=NULL;
      call*pptr=NULL;
      call*p2=new call;
      if(p1==startPtr)
         startPtr=startPtr->nextPtr;
      else//删除一般位置的节点
            {currentPtr=p1->nextPtr;
           deletePtr->nextPtr=currentPtr;}
      //p1=currentPtr;
      delete p1;//******************************************************************************************************
      cout<<"删除成功"<<endl;
      pptr=startPtr;//从链表头开始打印
      while(pptr!=NULL)
     {cout<<pptr->name<<"->";
      pptr=pptr->nextPtr;
     }
}
call* telephone::research(telephone &tel)//查找姓名
{   call*Ptrtel=startPtr;
    call*temPtr=startPtr;
    int i;
    int j=0;
   
    while(Ptrtel!=NULL)
    {    for(i=0;i<20;i++)
        { if(tel.Pname[i]!=Ptrtel->name[i])
            break;
        }//比较在第几个字符的地方,新添的对象与开始的位置不同
        if(i==20)
        {   if(Ptrtel!=startPtr)
                deletePtr=temPtr;//如果位置靠前,其删除位置就是其前面的指针
            return Ptrtel;//如果有找到该字符串,就返回其插入的位置
        }
        else
            if(i>=j)
            {    if((tel.Pname[i]-'a')>=(Ptrtel->name[i]-'a'))//如果字符位置靠后,
                {    solPtr=Ptrtel;//插入位置是就是这个地方
                    temPtr=Ptrtel;//得到它之前的位置的指针
                }
                else
                    solPtr=temPtr;//如果位置靠前,其插入位置就是其前面的指针
                j=i;//为了比较与那个字符的名字相似度最大
            }
        Ptrtel=Ptrtel->nextPtr;//循环查找
    }
    return Ptrtel;//没有找到,返回空值
}
void telephone::change(call*p)//改变成员的内容
{      int   m,n,i;
     call*p1=startPtr;
            cout<<"请修改新旧成员的名字吗?1----修改,2----不修改"<<endl;
            cin>>m;
            if(1==m)//如果想要改变成员的名字
            {    cout<<"请输入新的名字"<<endl;
                for(i=0;i<20;i++)
                    p->name[i]='\0';
                cin>>p->name;//输入名字
                while(p1!=NULL)
                {    for(i=0;i<20;i++)
                        if(p1->name[i]!=p->name[i])
                           break;//如果名字中有一个不相同就跳出与其的比较
                    p1=p1->nextPtr;//与下一个比较
                    if(i==20)//如果i==20说明该成员已经存在
                    {    getchar();
                        cout<<"该成员已经存在"<<endl;
                        cout<<"请输入新的名字"<<endl;
                        for(i=0;i<20;i++)
                           p->name[i]='\0';
                        cin>>p->name;
                        p1=startPtr;//输入新的名字,重新比较
                    }
                    if(p1==p)
                         p1=p1->nextPtr;//跳过与自己的比较
                }
                cout<<"修改成功"<<endl;
            }
            cout<<"想修改新旧成员的号码?1----修改,2----不修改"<<endl;
            cin>>n;//是否修改号码
            if(1==n)
            {    cout<<"请输入新的号码"<<endl;
                cin>>p->telenum;
                cout<<"修改成功"<<endl;
            }
}
void telephone::set1(char ch[20],telephone &tel)//设置类里面的成员
{    int i;
   
    for(i=0;i<20;i++)
       tel.Pname[i]=ch[i];
}
void telephone::set2(char ch1[12],telephone &tel)//设置类里面的成员
{    int i;
    for(i=0;i<12;i++)
       tel.Ptelenum[i]=ch1[i];
}
int main()
{      int i=0,j;
    int ocasion;//用于选择要用的功能
    char ch1;//在读文件时候,是否结束
    char newname[20];
    char newtelenum[12];//存储初始化新的对象的变量
    char ch;//用于判断是否继续操作的变量
    call*p;//用于输入到文件的指针
    call*ptr;//接收查找指针返回的位置,用于插入新的对象
    call*pptr=new call;   
    ofstream file;//建立输出流文件,把链表的信息读到文件
    ifstream tfile; //建立一个输入流文件,用于把文件中的信息读到链表中
    tfile.open("contact.dat");//打开文件
    if(tfile.fail())
        cout<<"fail"<<endl;//如果问价打开失败
    else//如果文件成功的打开
    {      ch1=tfile.get();//读取一个字符,判断是否空文件
          tfile.seekg(-1,ios::cur);//把指针退回到文件开始的时候
          if(((ch1-'A')>=0&&(ch1-'Z')<=0)||((ch1-'a')>=0&&(ch1-'z')<=0))//如果不是空文件
          { cout<<"电话本中已存在如下的成员"<<endl;
              while(!tfile.eof())   //如果文件没有结束
                {  tfile.getline(pptr->name,19,'\t');//读取前面的字符到指针的姓名数组中
                   tfile.seekg(3,ios::cur);//读取一个空字符和两个\t字符
                   tfile.getline(pptr->telenum,12);//读取剩下的字符到指针的号码数组中
                 for(j=0;j<20;j++)
                    if(((pptr->name[j]-'A')>=0&&(pptr->name[j]-'Z')<=0)||((pptr->name[j]-'a')>=0&&(pptr->name[j]-'z')<=0))
                    {}
                    else
                     pptr->name[j]='\0';//为了以后与新加入的成员姓名比较,就把不是字母的字符赋值为空
                 for(j=0;j<20;j++)
                    if(((pptr->telenum[j]-'0')>=0&&(pptr->telenum[j]-'9')<=0))
                    {}
                    else
                     pptr->telenum[j]='\0';//电话号码也是如此
                if(i<1)
                    startPtr=pptr;
                cout<<pptr->name<<"\t\t"<<pptr->telenum<<endl;
                pptr->nextPtr=NULL;//把指向下一个结构的指针赋值为空,
                ++i;//仅仅是为了只给StartPtr赋值一次
                ch1=tfile.get();//再次读取一个字符,判断是否文件结束
                tfile.seekg(-1,ios::cur);//后退一个字符到每一行的开始
                if(((ch1-'A')>=0&&(ch1-'Z')<=0)||((ch1-'a')>=0&&(ch1-'z')<=0))
                {}
                else
                    break;//如果下一行是空,跳出循环
                call*tr=new call;//没有结束就申请一个新的结构
                pptr->nextPtr=tr;//把新申请的结构加入链表
                pptr=pptr->nextPtr;//把下一个结构的地质赋值给pptr
            }
          }
         tfile.close();//关闭文件
    }
    file.open("contact.dat",ios_base::trunc);//定义一个文件,用trunc方式打开
    telephone newone;//构建一个新的类
    cout<<"开始操作吗?Y/N"<<endl;
    cin>>ch;
    while(ch=='Y')
    {   cout<<"请输入你要使用的功能:"<<endl;
        cout<<"1--------添加成员"<<endl;
        cout<<"2--------删除成员"<<endl;
        cout<<"3--------查找成员"<<endl;
        cout<<"4--------编辑成员"<<endl;
        cin>>ocasion;
        for(i=0;i<20;i++)
            newname[i]='\0';
        for(i=0;i<12;i++)
            newtelenum[i]='\0';
        switch(ocasion)
        {
            case 1://添加新成员
                cout<<"请输入新成员的名字"<<endl;
                cin>>newname;
                getchar();//
                cout<<"请输入新成员的电话号码"<<endl;
                cin>>newtelenum;
                newone.set1(newname,newone);
                newone.set2(newtelenum,newone);//给类里面的私有成员赋值
                if(startPtr==NULL)//如果新添加的对象是第一个
                    newone.add(newone);    //用链表在相应位置添加
                else
                {    //如果新添加的对象不是第一个,就查找名字是否存在
                    while((ptr=newone.research(newone))!=NULL)
                    {   cout<<"该姓名已经存在"<<endl;
                        cout<<"请输入新成员的名字"<<endl;//查找不成功就提示不存在
                        for(i=0;i<20;i++)
                           newname[i]='\0';
                        getchar();
                        cin>>newname;
                        cout<<"请输入新成员的电话号码"<<endl;
                        for(i=0;i<12;i++)
                            newtelenum[i]='\0';
                        getchar();
                        cin>>newtelenum;
                        newone.set1(newname,newone);
                        newone.set2(newtelenum,newone);//给类里面的私有成员赋值
                    }
                    newone.add(newone);    //然后把符合要求的成员加进去
                }
                break;
            case 2://删除一个成员
                cout<<"请输入要删除成员的名字"<<endl;
                cin>>newname;
                newone.set1(newname,newone);//设置对象的私有成员
                while((ptr=newone.research(newone))==NULL)
                {   cout<<"该成员不存在,请输入正确的名字"<<endl;//如果在链表中没有找到,提示该成员不存在
                    cout<<"请输入要删除的名字"<<endl;
                    getchar();
                    for(i=0;i<20;i++)
                         newname[i]='\0';
                    cin>>newname;
                    newone.set1(newname,newone);//给类里面的私有成员赋值
                }
                newone.delete_num(ptr);//找到就删除
                break;   
            case 3://查找一个成员
                cout<<"请输入目标成员的名字"<<endl;
                cin>>newname;
                newone.set1(newname,newone);//设置对象的私有成员
                if((ptr=newone.research(newone))==NULL)
                {    getchar();
                    while((ptr=newone.research(newone))==NULL)
                    {    cout<<"该成员不存在,请输入正确的名字"<<endl;//如果在链表中没有找到,提示该成员不存在
                        cout<<"请输入要查找的名字"<<endl;
                        for(i=0;i<20;i++)
                            newname[i]='\0';
                        cin>>newname;
                        newone.set1(newname,newone);//给类里面的私有成员赋值
                    }
                    cout<<"name"<<"           "<<ptr->name<<endl;
                    cout<<"phone_num"<<"      "<<ptr->telenum<<endl;
                }
                else
                {    cout<<"name"<<"           "<<ptr->name<<endl;
                    cout<<"phone_num"<<"      "<<ptr->telenum<<endl;
                }//找到就打印成员信息
                break;  
            case 4://修改一个成员信息
                cout<<"请输入目标成员的名字"<<endl;
                cin>>newname;
                newone.set1(newname,newone);//设置对象的私有成员
                if((ptr=newone.research(newone))==NULL)
                {    getchar();   
                    while((ptr=newone.research(newone))==NULL)
                    {    cout<<"该成员不存在,请输入正确的名字"<<endl;//如果在链表中没有找到,提示该成员不存在
                        cout<<"请输入新成员的名字"<<endl;
                        for(i=0;i<20;i++)
                            newname[i]='\0';
                        cin>>newname;
                        newone.set1(newname,newone);//给类里面的私有成员赋值
                    }
                    newone.change(ptr);//找到就改变信息
                    cout<<"name"<<"           "<<ptr->name<<endl;
                    cout<<"phone_num"<<"      "<<ptr->telenum<<endl;
                }
                else
                {    newone.change(ptr);//找到就改变信息
                    cout<<"name"<<"           "<<ptr->name<<endl;
                    cout<<"phone_num"<<"      "<<ptr->telenum<<endl;
                }
                break;
            default:
                cout<<"fail"<<endl;
                break;
        }
        getchar();
        cout<<endl<<"继续操作吗?  Y/N"<<endl;
        cin>>ch;
        if(ch=='N')//如果不再操作,就把链表打印到链表
        {   p=startPtr;
            while(p!=NULL)
            {    file<<p->name<<"\t\t\t"<<setiosflags(ios_base::left)<<p->telenum<<endl;
                p=p->nextPtr;
                file<<resetiosflags(ios_base::left);//设置相应的打印格式
            }
       
        }
    }
    //    delete pptr;
    //    delete tr;                     **************************************delete与free的区别
    file.close();
    system("pause");
return 0;
}
     
搜索更多相关主题的帖子: 成员 bug visual dev delete 
2010-09-18 09:23
mxs810
Rank: 9Rank: 9Rank: 9
来 自:火星
等 级:贵宾
威 望:16
帖 子:234
专家分:1122
注 册:2006-10-19
收藏
得分:5 
代码有点多,没有发现什么问题~~

授人以鱼不如授人以渔
2010-09-18 21:51
fishviv
Rank: 1
等 级:新手上路
帖 子:45
专家分:9
注 册:2010-9-10
收藏
得分:0 
就是在删除一个成员的时候,会有bug.在release版本中没有bug,但是再输入一个文件中已经有的姓名,就会有问题,不报重复.
2010-09-18 23:38
肖付
Rank: 2
等 级:论坛游民
帖 子:53
专家分:24
注 册:2010-9-11
收藏
得分:5 
会不会是编译器自身对其中的限制哦。
2010-09-20 15:04
快速回复:visual。猥琐。纠结人的bug。求救。。。关于电话本,在删除一个成员的 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026743 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved