通讯录工程的构建(一)

这个本是c语言课程设计的任务,完成这样一项工程还是花了不少时间,也学到了不少东西,应该说,c语言基本的东西全部能掌握了。

但是在编写的时候还是得到了许多教训。编写这样的大工程,首先要有清晰的思路,流程图什么的我是懒得画,但是得有个树状图,大体框架必须清楚。这一点HCM还是给了我不少启发。我习惯先写子函数,结果后来链表操作遇到文件保存的问题就傻了眼,幸好灵光一现想到转换成结构体数组。文件保存的时候我又一开始写进了子函数,最后写main函数的时候发现子函数里面的文件操作根本不需要,程序最后保存一下就好了。幸好文件的代码都差不多,才不至于做很多无用功。好了,废话不多说,进入正题吧。

 

这一篇是 main 函数的介绍,子函数下一篇再讲。

 

首先来解释一下结构体的组成:name,tel,email 为三个字符数组;sort用来存放联系人类型(办公,个人,商务);yn用来存放y 或者n,做判断依据;*next为链表尾指针。

定义了结构体之后,为方便起见,利用 typedef 将其简化为NODE标识。

struct stu

{

    char name[20],tel[13],email[30];

    char sort,yn;

    struct stu *next;

};

typedef struct stu NODE;

 

 

 

下面利用main函数来看一看整个程序的结构(” //--------中文”为解释,“//English” 为编程时的注释)。

 

  1 main()
  2 
  3 {
  4 
  5 //--------声明部分不看--------
  6 
  7  
  8 
  9     FILE *in,*f_name,*ll;
 10 
 11     NODE *head;
 12 
 13     int _new(NODE *head,char filename[]);
 14 
 15     NODE *create();
 16 
 17     int add(NODE* head);
 18 
 19     void check(NODE* head);
 20 
 21     int del(NODE* head);
 22 
 23     int func();
 24 
 25     int len,fun,lop=0,i;
 26 
 27     NODE stu[15];
 28 
 29     char ctn='y',yon;
 30 
 31     char fname[50];
 32 
 33     char ch;
 34 
 35     void trans(NODE* head,int len,NODE lin[]);
 36 
 37     void build(NODE* head,int len,NODE stu[]);
 38 
 39  
 40 
 41 //--------声明部分不看--------
 42 
 43  
 44 
 45 // read stu[]
 46 
 47  
 48 
 49 //--------利用file_name.dat 文件保存数据文件(如telbook.dat) 地址
 50 
 51  
 52 
 53 // open file address
 54 
 55 if((f_name=fopen("D:\\file_name.dat","rb"))==NULL)                                        
 56 
 57 {
 58 
 59             puts("\t\t*   cannot open the file1   *");
 60 
 61             exit(0);
 62 
 63 }
 64 
 65  
 66 
 67         rewind(f_name);
 68 
 69  
 70 
 71 //--------将地址保存在变量fname中
 72 
 73  
 74 
 75 fgets(fname,49,f_name);                                                        
 76 
 77 // note filename
 78 
 79  
 80 
 81 fclose(f_name);                                                                 
 82 
 83 // filename end
 84 
 85  
 86 
 87 //--------输出文件路径,下行可以注释掉
 88 
 89         printf("   filename:   %s   ",fname);
 90 
 91  
 92 
 93  
 94 
 95 //--------从len.dat文件读入节点个数len,字符型,因为文件存取不能对整型,用字符型进行操作。文件指针小写的LL ( *ll )
 96 
 97  
 98 
 99     if((ll=fopen("D:\\len.dat","rb"))==NULL)
100 
101     {
102 
103         puts("*   cannot open the file len   *");
104 
105         exit(0);
106 
107     }
108 
109  
110 
111     rewind(ll);
112 
113  
114 
115     ch=fgetc(ll);
116 
117  
118 
119     len=ch;
120 
121  
122 
123     fclose(ll);
124 
125  
126 
127 //--------读取结构体数组,存入变量stu[]中  (因为链表不能存入文件,所以将其转化成结构体数组进行存储)
128 
129  
130 
131     if((in=fopen(fname,"rb"))==NULL)
132 
133     {
134 
135         puts("\t\t*   cannot open the file2   *");
136 
137         exit(0);
138 
139     }
140 
141  
142 
143     rewind(in);
144 
145  
146 
147     for(i=0;i<len;i++)
148 
149             fread(&stu[i],sizeof(NODE),1,in);
150 
151  
152 
153     fclose(in);
154 
155  
156 
157 //printf("\nlen=%d\n",len);
158 
159  
160 
161 //--------将整个通讯录打印一遍
162 
163  
164 
165     printf("\n\n   ****************************   Phone Book   ****************************\n");
166 
167  
168 
169  
170 
171  
172 
173     for(i=0;i<len;i++)
174 
175         {
176 
177             printf("\n\t\t\tNO.%d\n\t\t\tName  : %s\n",i+1,stu[i].name);
178 
179             printf("\t\t\tTel   : %s\n",stu[i].tel);
180 
181             printf("\t\t\tSort  : %c\n",stu[i].sort);
182 
183             printf("\t\t\tEmail : %s\n",stu[i].email);
184 
185         }
186 
187     puts("\n\n");
188 
189     puts("\n\n*   Tips: when you enter 'sort' information, 'a' means official, 'b' means personal, 'c' means commercial   *\n");
190 
191  
192 
193 //--------创建表头 (create是建立头结点的函数)
194 
195     head=create();
196 
197  
198 
199 //--------将已读入的结构体数组转化为链表,方便操作(build为结构体数组转化为链表的函数)
200 
201     build(head,len,stu);
202 
203  
204 
205 //--------下面是操作界面,ctn代表continue
206 
207  
208 
209     while(ctn=='y')
210 
211     {
212 
213         //if(lop) fun=func();
214 
215     switch(func())
216 
217     {
218 
219         case 1: check(head);break;
220 
221         case 2: if(len>=15) {printf("\n\n\t\t*   The total number should be less than 15   *");break;}if(add(head)) len++;else puts("\n\n\t\t*    Add Fail    *");break;
222 
223 //--------case 2 首先判断节点是否已达到15,若是,则不进行add操作。进行add操作后,len要加一。
224 
225  
226 
227         case 3:  if(revise(head));else puts("\n\n\t\t*    Revise Fail    *");break;                                 
228 
229  //--------如果修改不成功,则输出修改失败
230 
231  
232 
233         case 4:  if(del(head)) len--;else puts("\n\n\t\t*    Delete Fail    *");break;
234 
235 //--------进行delete操作后,len要减一。
236 
237  
238 
239         case 5:  printf("\n\n\n");
240 
241                     printf("\t\t*  Do you want to create a new phone book and destroy the previous phone book?(y/n)  *");              
242 
243                     getchar();
244 
245                     yon=getchar();
246 
247                     getchar();
248 
249 //--------先让用户确定是否新建一个通讯录并且摧毁已有的通讯录
250 
251                     if(yon=='y')
252 
253                     {
254 
255                         //printf("entered");
256 
257                         head=create();
258 
259                         len=_new(head,fname);
260 
261 //--------将新通讯录长度传回main函数
262 
263                     }
264 
265                         puts("\n\n\t\t*      Create End      *");
266 
267  
268 
269                         break;
270 
271         case 6:     printf("\n\n   ****************************   Phone Book   ****************************\n");
272 
273  
274 
275         for(i=0;i<len;i++)
276 
277         {
278 
279             printf("\n\t\t\tNO.%d\n\t\t\tName  : %s\n",i+1,stu[i].name);
280 
281             printf("\t\t\tTel   : %s\n",stu[i].tel);
282 
283             printf("\t\t\tSort  : %c\n",stu[i].sort);
284 
285             printf("\t\t\tEmail : %s\n",stu[i].email);
286 
287         }
288 
289         getchar();
290 
291 //--------这里的getchar接受换行符
292 
293         break;
294 
295     }
296 
297     hah1:printf("\n\n\t\t*     Continue?(y/n)     *");
298 
299     ctn=getchar();
300 
301     getchar();
302 
303     //printf("\nctn=%c",ctn);
304 
305  
306 
307 //--------如果既不输入y也不输入n,则返回询问句
308 
309     if(ctn!='y'&&ctn!='n') goto hah1;
310 
311     }
312 
313  
314 
315 //--------将链表转化为结构体数组进行保存(trans为转化函数)
316 
317     trans(head,len,stu);
318 
319  
320 
321 //--------把最终的通讯录打印一遍
322 
323     printf("\n\n   ****************************   Phone Book   ****************************\n");
324 
325  
326 
327         for(i=0;i<len;i++)
328 
329         {
330 
331             printf("\n\t\t\tNO.%d\n\t\t\tName  : %s\n",i+1,stu[i].name);
332 
333             printf("\t\t\tTel   : %s\n",stu[i].tel);
334 
335             printf("\t\t\tSort  : %c\n",stu[i].sort);
336 
337             printf("\t\t\tEmail : %s\n",stu[i].email);
338 
339         }
340 
341         puts("\n\n");
342 
343  
344 
345 //--------将结构体数组保存进数据文件
346 
347     if((in=fopen(fname,"wb"))==NULL)
348 
349     {
350 
351         puts("\t\t*   Cannot open the file   *");
352 
353         exit(0);
354 
355     }
356 
357  
358 
359     rewind(in);
360 
361  
362 
363     for(i=0;i<len;i++)
364 
365         fwrite(&stu[i],sizeof(NODE),1,in);
366 
367  
368 
369     fclose(in);
370 
371  
372 
373 //--------将len保存进len.dat文件
374 
375     if((in=fopen("D:\\len.dat","wb"))==NULL)
376 
377     {
378 
379         puts("\t\t*   Cannot open the file   *");
380 
381         exit(0);
382 
383     }
384 
385  
386 
387     rewind(in);
388 
389  
390 
391     fputc(len,in);
392 
393     fclose(in);
394 
395  
396 
397     //printf("\nlen=%d",len);
398 
399  
400 
401     puts("\n\n\t\t*      Program End      *");
402 
403 }

 

posted @ 2015-06-04 08:56  Numerz  阅读(300)  评论(0编辑  收藏  举报