承接上一个debug practise这个是我修改完的版本,可以运行但是健壮性不强,因为是练习程序所以无需多做修改,大家参照即可
#include <iostream> #include <cctype> #include <cstdlib> #include <fstream> #include <cstring> using namespace std; const int MaxSize = 50; //电话簿成员数组大小 const int Size = 20; //文件名数组大小 typedef struct{ //电话簿结构 char name[MaxSize]; //名字 char tel[MaxSize]; //电话 }book; typedef struct LNode{ //链表结构 book *data; //电话簿数据 struct LNode *next; //后继结点指针 }LNode,*LinkList; LinkList InitList(LinkList *L); bool GetList(LinkList L,int *cont); bool InsertList(LinkList L,int insloc); bool DeleteList(LinkList L,int delloc); bool ChangeList(LinkList L,int chaloc); bool SearchList(LinkList L,int sealoc); void ShowList(LinkList L); void ShowMenu(); int LengthList(LinkList L); bool Checkname(char *); bool Checktel(char *); int main() { LinkList book; //创建链表存储结构 book = InitList(&book); //初始化链表 cout << "Initial List Success.\n"; ShowMenu(); //显示菜单 char oops; //用户输入控制变量 while(1){ cout.width(20); cout << "Enter a number that you need(# to quit): "; //用户操作界面 cin >> oops; switch(oops) { case '1': int cont; GetList(book,&cont); cout << cont << " have readed.\n"; break; case '2': int insloc; cout.width(15); cout << "Enter insert locate: "; cin >> insloc; InsertList(book,insloc); cout << "Insert Done.\n"; break; case '3': int delloc; cout << "Enter delete locate: "; cin >> delloc; DeleteList(book,delloc); cout << "Delete Done.\n"; break; case '4': int chanloc; cout << "Enter change locate: "; cin >> chanloc; ChangeList(book,chanloc); cout << "CHange Done.\n"; break; case '5': int searloc; cout << "Enter a search locate: "; cin >> searloc; SearchList(book,searloc); break; case '6': cout << "The list length is(Contains head node): " << LengthList(book) << endl; break; case '7': ShowList(book); cout << "This is your List.\n"; break; default : cout << "Done.\n"; return 0; } } return 0; } LinkList InitList(LinkList *L) { LNode *head; //声明头结点 head = (LinkList)malloc(sizeof(LNode)); //头结点开空间 if(!head) //头结点开空间失败 { cerr << "Err1.\n"; exit(EXIT_FAILURE); } head->data = (book *)malloc(sizeof(book)); //头结点data成员开空间 if(!head->data) //头结点data成员开空间失败 { cerr << "Err2.\n"; exit(EXIT_FAILURE); } head->next = NULL; //头结点next赋初值为空 return head; //返回头结点 } void ShowMenu() { cout << "Press 1 to Get Item From File.\n"; cout << "Press 2 to Insert.\n"; cout << "Press 3 to Delete.\n"; cout << "Press 4 to Change.\n"; cout << "Press 5 to Search.\n"; cout << "Press 6 to Show List Length(Contains head node).\n"; cout << "Press 7 to Show List.\n"; } bool GetList(LinkList L,int *cont) { LNode *p; //工作指针p p = L; //工作指针赋初值 char filename[Size]; //数据文件名 ifstream inFile; //文件流输入 cout << "Enter the data file name: "; getchar(); //吃掉回车 cin.getline(filename,Size); //输入文件名 inFile.open(filename); //打开文件 if(!inFile.is_open()) //如果打开文件失败 { cerr << "Could not open the file " << filename << endl; cerr << "Porgram terminating.\n"; exit(EXIT_FAILURE); } int count = 0; //正确输入数据个数 while(inFile.good() && !inFile.eof()){ //打开文件成功且文件没有结束 LNode *temp; //临时结构结点 temp = (LinkList)malloc(sizeof(LNode)); //临时结点开空间 if(!temp) //临时结点开空间失败 { cerr << "Err3.\n"; return false; } temp->data = (book *)malloc(sizeof(book)); //临时结点data成员开空间 if(!temp->data) //临时结点data成员开空间失败 { cerr << "Err4.\n"; return false; } inFile >> temp->data->name; //从文件读入名称 if(!Checkname(temp->data->name)) //名称非法 { delete(temp); //清除临时空间 continue; //进行下一次数据读入 } inFile >> temp->data->tel; //电话非法 if(!Checktel(temp->data->tel)) { delete(temp); //清除临时空间 continue; //进行下一次数据读入 } p->next = temp; //顺序移动指针 p = temp; //顺序移动工作指针 p->data = temp->data;//链表数据域赋值,这个一定要放在移动指针后,可保留头结点 count++; //正确读入个数+1 } p->next = NULL; //尾指针赋空 *cont = count; //带回正确输入个数 inFile.close(); //关闭文件 return true; } bool Checkname(char *a) { int len = strlen(a); //新字符串长 for(int i=0; i<len; i++){ //判断是否为字符 if(!isalpha(a[i])) return false; } return true; } bool Checktel(char *a) { int len = strlen(a); //新的字符串长 for(int i=0; i<len; i++){ //判断是否为数字 if(!isdigit(a[i])) return false; } return true; } void ShowList(LinkList L) { LNode *pshow = L->next; //建立指针指向头链表 while(pshow){ cout.width(10); cout << "name: " << pshow->data->name; cout.width(10); cout << " tel: " << pshow->data->tel << endl; pshow = pshow->next; } } bool InsertList(LinkList L,int insloc) { LNode *pins,*temp; //声明工作指针与临时指针 pins = L; //工作指针指向待操作链表 temp = (LinkList)malloc(sizeof(LNode)); //临时指针开空间 if(!temp) //临时指针开空间失败 { cerr << "Err 5.\n"; return false; } temp->data = (book *)malloc(sizeof(book)); //临时指针data成员开空间 if(!temp->data) //临时指针data成员开空间失败 { cerr << "Err 6.\n"; return false; } int ans = 1; //序数用来查找插入位置 while(pins && ans < insloc){ //当链表不为空且序数没到插入位置时 pins = pins->next; //移动工作指针 ans++; //序数+1 } if(!(pins->next)||ans>insloc) //如果越界或者序数大于插入位置 { cerr << "Err 7.\n"; //返回错误信息 return false; } cout << "Enter the new name: "; cin >> temp->data->name; //插入数据 if(!Checkname(temp->data->name)) //检查新输入数据是否合法 { cerr << "Enter the name Err. Err9.\n"; return false; } cout << "Enter the new tel: "; cin >> temp->data->tel; //插入新电话 if(!Checktel(temp->data->tel)) //检查新输入数据是否合法 { cerr << "Enter the tel Err. Err10.\n"; return false; } temp->next = pins->next; //当前工作指针的next给临时指针 pins->next = temp; //工作指针下一个指向temp return true; } bool DeleteList(LinkList L,int delloc) { LNode *pdel,*temp; //声明工作指针与临时指针 pdel = L; //工作指针指向待操作链表 int ans = 1; //序数用来查找删除位置 while(pdel && ans < delloc){ //当工作指针不为空且序数小于删除位置时 pdel = pdel->next; //工作指针后移 ans++; //序数+1 } if(!(pdel->next) || ans > delloc) //如果工作指针为空或者序数大于删除位置 { cerr << "Err 8.\n"; //返回错误信息 return false; } temp = pdel->next; //临时指针指向要删除位置 pdel->next = temp->next; //将删除位置的前驱指针指向删除位置的后继 delete(temp); //清除临时指针 return true; } bool ChangeList(LinkList L,int chaloc) { LNode *pcha,*temp; //声明工作指针与临时指针 pcha = L; //工作指针指向待操作链表 int ans = 1; //序数用来查找待修改位置 while(pcha && ans < chaloc){ //当工作指针不为空且序数小于修改位置时 pcha = pcha->next; //移动工作指针 ans++; //序数+1 } if(!(pcha->next) || ans > chaloc) //如果工作指针为空或者序数大于修改位置时 { cerr << "Err 9.\n"; //返回错误信息 return false; } temp = (LinkList)malloc(sizeof(LNode)); //临时结点开空间 if(!temp) //临时结点开空间失败 { cerr << "Err 10.\n"; return false; } temp->data = (book *)malloc(sizeof(book)); //临时结点data成员开空间 if(!temp->data) //临时结点data成员开空间失败 { cerr << "Err 16.\n"; return false; } cout << "Enter the name to change: "; //输入修改后名称 cin >> temp->data->name; if(!Checkname(temp->data->name)) //检查新输入名字是否合法 { cerr << "Enter the name Err. Err9.\n"; return false; } cout << "Enter the tel to change: "; //输入修改后号码 cin >> temp->data->tel; if(!Checktel(temp->data->tel)) //检查新输入号码是否合法 { cerr << "Enter the tel Err. Err10.\n"; return false; } pcha->next->data = temp->data; //修改数据 return true; } bool SearchList(LinkList L,int sealoc) { LNode *psea = L; //声明工作指针指向待操作链表 int ans = 1; //序数用来查找待查找位置 while(psea && ans < sealoc){ //当工作指针不为空且序数小于查找位置时 psea = psea->next; //移动工作指针 ans++; //序数+1 } if(!(psea->next) || ans > sealoc) //如果工作指针为空或者序数大于查找位置 { cerr << "Err 11.\n"; //返回错误信息 return false; } cout << "Your search item: " << endl; //输出查询数据 cout.width(10); cout << "name: " << psea->next->data->name; cout.width(10); cout << "tel: " << psea->next->data->tel; cout << endl; return true; } int LengthList(LinkList L) { LNode *pwork = L->next; //声明工作指针指向待操作链表 int count = 1; //计数 while(pwork){ //当工作指针不为空 pwork = pwork->next; //工作指针后移 count++; //计数+1 } return count; //返回计数值 }一个不甘堕落的大学生