|
|
用C语言编通讯录程序(初学者级别的) |
|
|
作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站 |
要求:有<显示所有文件>(list) <删除><插入><保存><读取><主菜单><退出><读入><查找> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 】*一个通信录管理程序有以下功能: . 插入新的通信记录; . 查找某人的通信记录; . 删除某人的通信记录; . 浏览通信录; . 结束程序运行。 设每条通信录包含以下内容: .姓名 .地址 .邮政编码 .电话号码 并设通信录全部以字符行形式存于文件中,每四个字符行构成一个通信录记录。 程序启动后,自动从指定的文件中读取通信录信息。程序运行结束后,又自动将内存中修改过的通信录 信息保护到文件中。为了查找,插入,删除等操作的方便,程序内部以双向链表形式组织通信录信息。设启 动程序的命令行可带通信录文件参数。如启动时未给出文件名参数,则程序首先要求用户键入通信录文件 名。程序运行时,反复显示请求输入操作命令的提示信息: 请输入命令: [i, f, d, s, q] 即要求用户打入一条命令,它可以是 i(插入)、f(寻找)、d(删除)、s(显示)以及q(结束程序运行)。如果打 入命令不是其中之一, 将详细显示命令符及其意义的说明: 命令表: i : 插入一条新的通信记录. f : 按输入名查找通信录. d : 按输入名删除一条通信录. s : 浏览通信录. q : 退出. 然后重新请求打入操作命令的提示信息。程序将全部通信录组织成一个双向勾链的链表。接受显示通信录表 的命令后,首先显示的是第一条通信录,由用户键入Up键或Down键分别实现向上或向下选择,显示下一条通信录。键入Escape键结束显示命令。上述三键在显示一条通信录之后,在下面给出提示。按其他键不予理睬.
                      #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXL 120
typedef struct saddr { char *name; char *address; char *zip; char *phone; struct saddr *next, *pre; } ADDR;
char buffer[MAXL], fname[40]; FILE *fp; int modified = 0;
ADDR *load(); void insert(), make(), find(), del(), display(), show(), save(), freeall(), usage(); int getstr(FILE*, char **), getbuffer(FILE *);
int main(int argc, char **argv) { ADDR *head; char c; if (argc == 1) { printf("请输入通信录文件名. "); scanf("%s%*c", fname); } else{ strcpy(fname, *++argv); } head = load(fname); while (1) { printf("\n请输入命令: [i, f, d, s, q]\n"); while (getbuffer(stdin) == 0); if ((c = buffer[0]) == 'q') { if (modified) { printf("修改后的通信录未保存,要保存吗?(y/n) "); while (!(((c = getchar()) >= 'a' && c <= 'z') ¦¦ (c >= 'A' && c <= 'Z')))continue; if (c == 'y' ¦¦ c == 'Y') save(head, fname); } freeall(head); break; } switch © { case 'i' : insert(head); break; case 'f' : find(head); break; case 'd' : del(head); break; case 's' : show(head); break; default : usage(); break; } }//while (1) return 0; }//int main
/* 输入新的通信录 */ void insert( ADDR *ptr) { char *spt; ADDR *p;
while (1) { printf("名字? (立即回车表示结束) "); if (getstr(stdin, &spt) ==0) break; p = (ADDR *)malloc(sizeof(ADDR)); p->name = spt; printf("地址? "); getstr(stdin, &p->address); printf("邮编? "); getstr(stdin, &p->zip); printf("电话号码? "); getstr(stdin, &p->phone); p->next = NULL; p->pre = NULL; make(ptr, p); modified = 1; } } /* 将*p插入链表 */ void make(ADDR *ptr, ADDR *p) { ADDR *pre, *suc; pre = ptr; suc = pre->next; while (suc) { if (strcmp(suc->name,p->name) >= 0) break; pre = suc; suc = pre->next; } pre->next = p; p->pre = pre; p->next = suc; if(suc) suc->pre = p; } void find( ADDR *ptr ) { ADDR *p; printf("输入寻找的名: "); while (getbuffer(stdin) == 0); p = ptr->next; while (p) { if (strcmp(buffer, p->name) == 0) break; p = p->next; } if (p) display(p); else printf("末找到!\n"); } /* 删除指定的通信录 */ void del( ADDR *ptr ) { ADDR *pre, *suc; printf("输入要删除的通信录的名: "); while (getbuffer(stdin) == 0) ; /* 跳过空行 */ pre = ptr; suc = pre->next; while (suc) { if (strcmp(suc->name, buffer) == 0) break; pre = suc; suc = pre->next; } if (suc) { if (suc->next) suc->next->pre = pre; pre->next = suc->next; free(suc->name); free(suc->address); free(suc->phone); free(suc->zip); free(suc); modified = 1; } else printf("Not found !\n"); } void display( ADDR *ptr ) { printf("\n\t名 : %s\n", ptr->name); printf("\t地址 : %s\n", ptr->address); printf("\t邮编 : %s\n", ptr->zip); printf("\t电话 : %s\n", ptr->phone); } /* 告知命令用法 */ void usage() { printf("\n命令表:\n"); printf("i : 插入一条新的通信录.\n"); printf("f : 按输入名寻找通信录.\n"); printf("d : 按输入名删除一条通信录.\n"); printf("s : 浏览通信录.\n"); printf("q : 退出.\n"); } /* 保存通信录到文件 */ void save(ADDR *head, char *fname) { FILE *fp; ADDR *p;
p = head->next; if ((fp = fopen(fname, "w")) == NULL) { fprintf(stderr, "Can't open %s.\n", fname); return; } while (p != NULL) { fprintf(fp, "%s\n%s\n%s\n%s\n", p->name, p->address, p->zip, p->phone); p = p->next; } fclose(fp); } /* 从文件读出通信录,建立双向链表 */ ADDR *load(char *fname) { ADDR *p, *h;
h = (ADDR *)malloc(sizeof(ADDR)); h->pre = NULL; h->next = NULL; if ((fp = fopen(fname, "r")) == NULL) return h; /* 原先没有文件,返回空链表 */ while (!feof(fp)) { p = (ADDR *)malloc(sizeof(ADDR)); if(getstr(fp, &p->name) == 0) { free(p); break; } getstr(fp, &p->address); getstr(fp, &p->zip); getstr(fp, &p->phone); make(h, p); } fclose(fp); return h; } /* 从文件读入一行,并删除前导和尾随空白符后保存于堆空间 */ int getstr(FILE *rfp, char **s) { int len; if ((len = getbuffer(rfp)) == 0) { *s = NULL; return 0; } *s = (char *)malloc(len+1); strcpy(*s, buffer); return len; } /* 从文件读入一行,并删除前导和尾随空白符后保存于buffer */ int getbuffer(FILE *rfp) { int len; char *hp, *tp; if (fgets(buffer, MAXLEN, rfp) == NULL) return 0; hp = buffer; while(*hp == ' ' ¦¦ *hp == '\t') hp++; tp = hp + strlen(hp) - 1; while (tp >= hp && (*tp == ' ' ¦¦ *tp == '\t' ¦¦ *tp == '\n')) tp--; *(tp+1) = '\0'; for(tp = buffer; *tp++ = *hp++;); len = strlen(buffer); return len; } /* 释放内存空间 */ void freeall(ADDR *head) { ADDR *p; p = head->next; free(head); while (p != NULL) { if (p->name != NULL) free(p->name); if (p->address != NULL) free(p->address); if (p->phone != NULL) free(p->phone); if (p->zip != NULL) free(p->zip); head = p->next; free(p); p = head; } } void show( ADDR *ptr ) { ADDR *p; ……………………………… TO BE CONTINUED…………
|
|
相关文章:相关软件: |
|