C++链表做通讯录莫名异常

C++链表做通讯录莫名错误
用链表做了个通讯录,但是发现两个问题:
1;输入一个人的数据后居然提示没有数据
C++链表做通讯录莫名异常
2:输入一次数据后再次选择2进行下一次输入后程序就会突然中止
C++链表做通讯录莫名异常
头文件:
#include<string>
using namespace std;
struct contact{
string num;
string name;
string tel;
contact *next;
};
                void display(contact*);
void create(contact*,contact*,contact *);
void change(contact*,contact*,contact *);
void output();
主函数:
#include<iostream>
#include<string>
#include"touwenjian.h"
using namespace std;
int i=0;
int main(){
contact *head=NULL;
contact *p1,*p2;
p1=p2=head;
int n;
while(1){
output();
cin>>n;
switch(n){
case 1:display(head);break;
case 2:create(head,p1,p2);break;
case 3:change(head,p1,p2);break;
case 4:return 0;
default:cout<<"Error number"<<endl;
}
}
}
函数定义:
#include<iostream>
#include<string>
#include"touwenjian.h"
using namespace std;
extern int i;
void output(){
cout<<"1:显示当前通讯录内容 2:添加联系人 3:查看和修改联系人 4:退出"<<endl;
}
void create(contact *head,contact *p1,contact *p2){
if(!i)
{
head=new contact;
head->next=NULL;
cout<<"请输入TA的学号:"<<endl;
 cin>>head->num;
 cout<<"请输入TA的姓名:"<<endl;
 cin>>head->name;
 cout<<"请输入TA的电话号码:"<<endl;
 cin>>head->tel;
 i++;}
 else {
  p1=new contact;
  cout<<"请输入TA的学号:"<<endl;
 cin>>p1->num;
 cout<<"请输入TA的姓名:"<<endl;
 cin>>p1->name;
 cout<<"请输入TA的电话号码:"<<endl;
 cin>>p1->tel;
     p2->next=p1;
 p2=p1;
 p1->next=NULL;
 i++;}
 }
void display(contact *head){
if(i==0||head==NULL) 
cout<<"通讯录里还没有人哦!快点输入数据吧~"<<endl;
else {
contact *p=head;
while(p!=NULL){
cout<<"学号:"<<p->num<<"姓名:"<<p->name<<"电话号码:"<<p->tel<<endl;
p=p->next;
}
}
}
void change(contact *head,contact *p1,contact *p2){
  int flag=1;
  if(!i) 
cout<<"通讯录里还有没人哦!快点输入数据吧~"<<endl;
  else {
 cout<<"你想通过什么方式找这个人?"<<"   "<<"1.学号 2.姓名 3.电话号码"<<endl;
  int n;
  cin>>n;
  string target;
  if(n==1){
  cout<<"TA的学号是啥呀?"<<endl;
    cin>>target;
head=p1;
while(p1->num!=target&&p1->next!=NULL)
{p2=p1;p1=p1->next;}
if(p1->num==target){
cout<<"学号:"<<p1->num<<endl;
cout<<"姓名:"<<p1->name<<endl;
cout<<"电话号码:"<<p1->tel<<endl; 
}
else {
cout<<"找不到这个人哦!"<<endl;
flag=0;}
}
else if(n==2){
  cout<<"TA的名字是啥呀?"<<endl;
    cin>>target;
head=p1;
while(p1->name!=target&&p1->next!=NULL)
{p2=p1;p1=p1->next;}
if(p1->name==target){
cout<<"学号:"<<p1->num<<endl;
cout<<"姓名:"<<p1->name<<endl;
cout<<"电话号码:"<<p1->tel<<endl; 
}
else {
cout<<"找不到这个人哦!"<<endl;flag=0; }
}
else 
{cout<<"TA的电话号码是啥呀?"<<endl;
    cin>>target;
head=p1;
while(p1->tel!=target&&p1->next!=NULL)
{p2=p1;p1=p1->next;}
if(p1->tel==target){
cout<<"学号:"<<p1->num<<endl;
cout<<"姓名:"<<p1->name<<endl;
cout<<"电话号码:"<<p1->tel<<endl; 
}
else {
cout<<"找不到这个人哦!"<<endl;flag=0;}
 }
 if(flag){
  cout<<"你想对"<<p1->name<<"的数据做什么操作?"<<endl;
  cout<<"1.删除 2.修改"<<endl;
  int m;
  cin>>m;
  if(m==1){
  if(p1==head){
  contact *p=head;
  head=head->next;
  delete p;
 }
 else{
 p2->next=p1->next;
 delete p1;
}
}
if(m==2){
cout<<"请输入新数据:"<<endl;
cout<<"学号:";
cin>>p1->num;
cout<<"姓名:" ;
cin>>p1->name;
cout<<"电话号码:";
cin>>p1->tel; 
}
 }
 }
 }
------解决思路----------------------
create函数,在i为1的时候,进else分支,else分支里面这句话 p2->next=p1;出错。p2此时是空指针。

这程序bug比较多,建议再学习一下基础指针知识。看看《高质量C++编程》吧,明确说了这个地方的指针作参数在函数内部new的处理,会对初学者有点帮助
------解决思路----------------------
这样才能改变指针的指向

case 2:create(&head,&p1,&p2);break;

void create(contact **head,contact **p1,contact **p2)
{
if(!i)
{
*head=new contact;
(*head)->next=NULL;
cout<<"请输入TA的学号:"<<endl;
cin>>(*head)->num;
cout<<"请输入TA的姓名:"<<endl;
cin>>(*head)->name;
cout<<"请输入TA的电话号码:"<<endl;
cin>>(*head)->tel;
*p2 = *head;
i++;
}
else
{
  *p1=new contact;
  cout<<"请输入TA的学号:"<<endl;
cin>>(*p1)->num;
cout<<"请输入TA的姓名:"<<endl;
cin>>(*p1)->name;
cout<<"请输入TA的电话号码:"<<endl;
cin>>(*p1)->tel;
(*p2)->next=(*p1);
*p2=*p1;
(*p1)->next=NULL;
i++;
}
}