昨天和今天一直在磕这个小项目,由于近来学习了单链表的相关知识,所以想趁周末做一个通讯录的小项目,主要功能就是增,删,插入。
但是意外重重 在做这个小项目的过程中有几点深入的体会:
- 应该深入学习一下软件工程,了解软件是如何设计的,因为在写完功能之后再写主界面时,感觉十分混乱。没有办法画一个清晰的逻辑框图,也可能是原来的项目都是有人设计好,第一次自己去设计,要多加练习;
- 深入学习一下c语言标准库,从而对系统定义的函数有更好的操作性;
先上一下这个失败的代码吧
1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef struct NODE 4 { 5 int num; 6 char *name; 7 int idnum; 8 char *prof; 9 char *tel; 10 struct NODE *next; 11 }Node; 12 Node *GetNode(int num,char *name,int idnum,char *prof,char *tel); 13 void AddNode(Node **ppHead,Node **pEnd,Node *pNode); 14 void InsertNode(Node **ppHead,Node **ppEnd,Node *pNode,int num); 15 void DeleteNode(Node **ppHead,Node **ppEnd,int num); 16 17 int main() 18 { 19 Node *pHead = NULL; 20 Node *pEnd = NULL; 21 int ChooseNum; 22 int num; 23 int Insertnum; 24 int Deletenum; 25 char name[50] = {0}; 26 int idnum; 27 char prof[50] = {0}; 28 char tel[50] = {0}; 29 int i; 30 printf("-----------------------------------------------\n"); 31 printf(" \n"); 32 printf(" 通讯录 \n"); 33 printf(" \n"); 34 printf("-----------------------------------------------\n"); 35 while(1) 36 { 37 printf("1-----------添加\n"); 38 printf("2-----------插入\n"); 39 printf("3-----------删除\n"); 40 printf("4-----------查看\n"); 41 printf("5-----------退出\n"); 42 printf("请选择: "); 43 scanf("%d",&ChooseNum); 44 switch (ChooseNum) 45 { 46 case 1: 47 printf("请输入序号: "); 48 scanf("%d",&num); 49 printf("请输入姓名: "); 50 scanf("%s",&name); 51 printf("请输入学号: "); 52 scanf("%d",&idnum); 53 printf("请输入专业: "); 54 scanf("%s",&prof); 55 printf("请输入联系电话: "); 56 scanf("%s",&tel); 57 AddNode(&pHead,&pEnd,GetNode(num,name,idnum,prof,tel)); 58 break; 59 case 2: 60 printf("请输入插入序号: "); 61 scanf("%d",&Insertnum); 62 printf("请输入序号: "); 63 scanf("%d",&num); 64 printf("请输入姓名: "); 65 scanf("%s",name); 66 printf("请输入学号: "); 67 scanf("%d",&idnum); 68 printf("请输入专业: "); 69 scanf("%s",prof); 70 printf("请输入联系电话: "); 71 scanf("%s",tel); 72 InsertNode(&pHead,&pEnd,GetNode(num,name,idnum,prof,tel),Insertnum); 73 break; 74 case 3: 75 printf("请输入删除序号: "); 76 scanf("%d",&Deletenum); 77 DeleteNode(&pHead,&pEnd,Deletenum); 78 case 4: 79 printf("\n\n\n\n"); 80 printf("序号 姓名 学号 专业 联系方式\n"); 81 while(pHead!=NULL) 82 { 83 printf("%-12d%-12s%-12d%-12s%-12s\n",pHead->num,pHead->name,pHead->idnum,pHead->prof,pHead->tel); 84 pHead = pHead->next; 85 } 86 printf("\n\n\n\n"); 87 break; 88 case 5: 89 printf("欢迎再次使用 谢谢!\n"); 90 break; 91 default: 92 printf("输入错误!!!\n"); 93 break; 94 } 95 if(ChooseNum == 5) 96 break; 97 //while(i==50) 98 //{ 99 // name[i] = 0; 100 // prof[i] = 0; 101 // tel[i] = 0; 102 //} 103 printf("------------------------------------------------\n"); 104 } 105 106 107 108 return 0; 109 } 110 Node *GetNode(int num,char *name,int idnum,char *prof,char *tel) 111 { 112 Node *pTemp = (Node *)malloc(sizeof(Node)); 113 pTemp->num = num; 114 pTemp->name = name; 115 pTemp->idnum = idnum; 116 pTemp->prof = prof; 117 pTemp->tel = tel; 118 pTemp->next = NULL; 119 120 return pTemp; 121 } 122 void AddNode(Node **ppHead,Node **ppEnd,Node *pNode) 123 { 124 if(*ppHead == NULL) 125 { 126 *ppHead = pNode; 127 *ppEnd = pNode; 128 } 129 else 130 { 131 (*ppEnd)->next = pNode; 132 *ppEnd = pNode; 133 } 134 } 135 void InsertNode(Node **ppHead,Node **ppEnd,Node *pNode,int num) 136 { 137 Node *pMark = *ppHead; 138 if((*ppHead)->num = num) 139 { 140 pNode->next = *ppHead; 141 *ppHead = pNode; 142 return ; 143 } 144 while((pMark->next)!=NULL) 145 { 146 if(pMark->next->num = num) 147 { 148 pNode->next = pMark->next; 149 pMark->next = pNode; 150 return; 151 } 152 } 153 (*ppEnd)->next = pNode; 154 *ppEnd = pNode; 155 return ; 156 157 } 158 void DeleteNode(Node **ppHead,Node **ppEnd,int num) 159 { 160 Node *pMark = *ppHead; 161 Node *pDelete = NULL; 162 if((*ppHead)->num == num) 163 { 164 pDelete = *ppHead; 165 *ppHead = (*ppHead)->next; 166 free(pDelete); 167 pDelete = NULL; 168 } 169 while(pMark->next != NULL) 170 { 171 if(pMark->next->num == num) 172 { 173 pDelete = pMark->next; 174 pMark->next = pDelete->next; 175 free(pDelete); 176 pDelete =NULL; 177 return ; 178 } 179 if(pMark->next = (*ppEnd)) 180 { 181 pDelete = (*ppEnd); 182 *ppEnd = pMark; 183 (*ppEnd)->next = NULL; 184 free(pDelete); 185 pDelete = NULL; 186 return; 187 } 188 pMark = pMark->next; 189 } 190 }
纠结很长时间的地方集中于,字符串输入这一方面:
- 第一次考虑在主函数中存储字符串应用 字符数组 的方式,但结果是打印这个通讯录时,后面一个结点所有的字符串会把前面所有的字符串覆盖掉,在分析之后发现,从scanf()输入到字符数组里,再传入到GetNode()这其中的步骤都可正常运行,但是当第二次甚至更多次添加节点的时候 在GetNode()的函数中 结构体内字符串型指针都会指向 main函数里的数组首元素地址,就导致我在更新字符数组后,之前结点内的字符串也会跟着改变。体现出来就是之前结点内字符串会被最后一个结点内字符串所覆盖;
- 第二次考虑设置一个char *的指针,我本以为scanf()内输入字符串为输入字符串的地址,但实际却不是这样,编译器提示输入位置冲突(具体原因我再进一步研究,因为假设是按字符输入的话,我把字符输入进一个空间内,也没什么毛病呀)
- 第三次考虑给char *指针 在堆区开一个空间,结果是编译器在输出的时候报错,下断点调试的时候发现,字符串根本没有存进指针内。
- 第四次考虑利用getchar()单个存入我开在堆区的空间里,后来由于getchar()是用来显示我存在缓冲区内的函数,在输入字符串前,还有其他数字和\n出现,就会导致这个程序会提前结束,代码如下:
1 char *name = (char *)malloc(5); 2 char *pMark = name; 3 char c; 4 while((c = getchar()) != '\n') 5 { 6 *pMark = c; 7 pMark++; 8 }
这个项目还得继续研究,重点集中于 如何存储字符串,除了用字符数组的方式,和scanf()的作用原理,正好买了《c标准库》这本书 能研究一下
2019-04-21 19:16:35 编程小菜鸟反思,大佬勿喷,谢谢!!!