C语言实现加密通讯录雏形

本程序用C写成,鼓励批评指正! 
Name:Contact++ 
Version:0.2 
Powered By GenialX 
From 沈阳化工大学2011级 
URL:胡旭-煦生活 - 胡旭个人博客 - 一个自由大学生的琐碎 
QQ:2252065614 
QQ交流群:235173087(欢迎加入,增增人气儿...) 
---2013.02.07 
基本功能实现: 
通讯录信息插入、删除、编辑、查找、修改以及信息存盘(contact.ctt)。 

实现原理: 
利用指针操作链表实现通讯录功能。 

记录: 
添加给存盘文档加密的功能(存档文件即根目录下的contact.ctt文件) 
详细:利用异或加密,由于异或操作的特性,所以加密和解密调用,同一个实现即可。 
步骤: 
1、定义密钥常量KEY(默认值为'x')。 
2、修改getInfo()函数。首先创建一个临时文件tmp.ctt(属性设置成系统隐藏文件),然后把源文件(加密文件)读取,并将解密后的内容放入tmp.ctt中。然后将tmp.ctt中的内容逐步读入链表,之后删除临时文件tmp.ctt。 
3、修改saveRecords()函数。原理基本同上,创建系统隐藏文件作为临时缓冲文件(tmp.ctt),之后删除。 
---2013.02.07  21:01 
定义常量 
详细:将一些信息定一场全局常量,便于管理。比如:作者信息。 
---2013.02.08  08:26 
源码:

  1 /**

  2  * @Name:Contact++

  3  * @Desc:这是一个实现通讯录的C源代码

  4  * @Version:0.2

  5  * @Author:GenialX

  6  * @From:沈阳化工大学2011级

  7  * @URL:http://www.ihuxu.com

  8  * @QQ:287156904

  9  * @QQ Group:235173087

 10  */

 11 

 12 #include <stdio.h>

 13 #include <stdlib.h>

 14 #include <string.h>

 15 #include <windows.h>

 16 

 17 //这里定义的是联合体中字符数组的长度。

 18 #define C_NAME_SIZE 10

 19 #define C_SEX_SIZE 3

 20 #define C_AGE_SIZE 5

 21 #define C_PHONE_SIZE 12

 22 #define C_QQ_SIZE 12

 23 #define C_PROVINCE_SIZE 20

 24 #define C_CITY_SIZE 20

 25 #define C_COMMENT_SIZE 100

 26 

 27 //亲,很明显,这是函数说明!

 28 void insRecord();//插入一条记录的实现

 29 void inputs(char *prompt,char *info,int count);//插入一条记录时,逐行输入信息的实现

 30 struct addr *linkNode(struct addr *i,struct addr *top);//输入完一条记录后,将当前的缓冲节点连接到链表中的实现

 31 struct addr *find(char *name);//查找出指定的节点的实现

 32 void seaRecord();//查找记录的实现

 33 void delRecord();//删除记录的实现

 34 int selectMenu();//主菜单的实现

 35 void disRecord(addr *info);//显示一条记录的实现

 36 void disRecords();//显示全部记录的实现

 37 void getInfo(); //根据ctt文本中的记录,逐条返回数据项,并实现将信息插入链表,即程序启动的初始化状态的实现

 38 void initInputs(char *initInfo[]);//输入完一条记录后,将当前的缓冲节点连接到链表中的实现

 39 void saveRecords();//将链表中的信息全部写到磁盘文件中的实现

 40 void saveToFile(addr *info);//将每条信息记录放到新建的文件中的实现

 41 void editRecord();//修改记录的实现

 42 void about();//显示作者信息的实现

 43 

 44 

 45 //全局的东东

 46 

 47 //联合体

 48 struct addr

 49 {

 50     char c_name[C_NAME_SIZE];

 51     char c_sex[C_SEX_SIZE];

 52     char c_age[C_AGE_SIZE];

 53     char c_phone[20];

 54     char c_qq[C_QQ_SIZE];

 55     char c_province[C_PROVINCE_SIZE];

 56     char c_city[C_CITY_SIZE];

 57     char c_comment[C_COMMENT_SIZE];

 58 

 59     struct addr *next;//pointer to next entry ^^

 60 };

 61 

 62 //全局指针变量,info存储当前缓冲的节点、start和last存储最后一个节点、head存储头节点

 63 struct addr *info,*start,*last,*head;

 64 //初始化用,与head有关的变量

 65 static int n = 0;

 66 //加密常量

 67 const char KEY='x';

 68 //作者信息

 69 const char AUTHOR[] = "乌鸟";

 70 const char VERSION[] = "0.2";

 71 const char DESC[] = "本程序用C写成,鼓励批评指正!";

 72 const char QQ[] = "235173087(欢迎加入,增增人气儿...)";

 73 const char URL[] = "http://www.ihuxu.com";

 74 const char FROM[] = "沈阳化工大学2011级";

 75 const char TIME[] = "2013.02.08";

 76 const char APPNAME[] = "Contact++";

 77 

 78     /**

 79      * @desc 显示系统菜单的实现

 80      */

 81     int selectMenu()

 82     {

 83         char s[80];

 84         int c;

 85         printf(" ------------------------------- \n");Sleep(50);

 86         printf("|1.Insert a New Record          |\n");Sleep(50);

 87         printf("|2.Delete a Specific Record     |\n");Sleep(50);

 88         printf("|3.Search the Record            |\n");Sleep(50);

 89         printf("|4.Edit the Record              |\n");Sleep(50);

 90         printf("|5.Display All Records          |\n");Sleep(50);

 91         printf("|6.About                        |\n");Sleep(50);

 92         printf("|7.Quit                         |\n");Sleep(50);

 93         do

 94         {

 95             printf(" ------------------------------- \nEnter your choice:");

 96             gets(s);

 97             c = atoi(s);//atoi(),把字符串转换为整形。

 98         }while(c<1||c>7);

 99         return(c);

100     }

101 

102     /**

103      * @desc 插入一条记录的实现

104      */

105     void insRecord()

106     {

107         struct addr *info;//声明缓冲节点,用来指向新记录的节点地址

108 

109         for(;;n++)

110         {

111             //分配地址给info

112             info = (struct addr *)malloc(sizeof(struct addr));

113             //内存不足的情况

114             if(info == NULL)

115             {

116                 printf("Out of memory!\n");

117                 return;//计算机脑容量不够了,结束了插入操作

118             }

119             printf("\nSet 0 to name to exit insert!");

120             inputs("Enter name",info->c_name,C_NAME_SIZE);

121             if(info->c_name[0] == '0')

122             {

123                 printf("\n");

124                 break;

125             }else{

126                     inputs("Enter sex",info->c_sex,C_SEX_SIZE);

127                     inputs("Enter age",info->c_age,C_AGE_SIZE);

128                     inputs("Enter phone",info->c_phone,C_PHONE_SIZE);

129                     inputs("Enter qq",info->c_qq,C_QQ_SIZE);

130                     inputs("Enter province",info->c_province,C_PROVINCE_SIZE);

131                     inputs("Enter city",info->c_city,C_CITY_SIZE);

132                     inputs("Enter comment",info->c_comment,C_COMMENT_SIZE);

133                     start = linkNode(info,start);//感觉start和last存的是一个节点

134                     if(n == 0)

135                     {

136 //                        printf("\nhead has been initialized\nn:%d",n);

137                         head = start;//head就是头结点

138                     }

139             }

140         }

141     }

142     

143 /**

144  * @desc 插入一条记录时,逐行输入信息的实现

145  * @parame char *promot,提示信息

146  * @parame char *info,存储用户输入数据的节点

147  * @parame int count,数据项最大字节数

148  */

149 void inputs(char *prompt,char *info,int count)

150 {

151     char p[50];

152     do

153     {

154         printf("\n%s:",prompt);

155         gets(p);

156 //        puts(p);

157         if(strlen(p)/2>count)

158         {

159             printf("Too long!\n");

160         }

161     }while(strlen(p)/2>count);

162         strcpy(info,p);//将本函数的p地址复制给缓冲info地址

163 //        puts(info);

164 }

165 

166 /**

167  * @desc 在输入好新的消息记录后,需要将新的节点连接在链表中

168  */

169 struct addr *linkNode(struct addr *current,struct addr *top)

170 {

171     if(!last)

172     {

173         last = current;

174         current->next = NULL;

175         return(current);

176     }

177     else

178     {

179         top->next=current;

180         current->next=NULL;

181         last = current;

182         return(current);

183     }

184 }

185 

186 /**

187  * @desc 查找出指定的节点的实现

188  * @return addr *,指定姓名的指针

189  */

190 struct addr *find()

191 {

192     struct addr *info;

193     info = head;

194     int flag;

195     char str[20];

196 

197     printf("按类别查找 1:名字;2:电话;3:QQ;4:省份;5:城市\n");Sleep(50);

198     printf("请输入相应数字:");

199     scanf("%d",&flag);

200 //    printf("%d",flag);

201     getchar();

202     printf("请输入数据:");

203     gets(str);

204 //    puts(str);

205 

206     //我实在是找不着办法如何动态改变info->后面的东西,正好,让我知道知道什么叫面向过程编程!嘻嘻...

207     switch(flag)

208     {

209         case 1:{

210                 while(info)

211                     {

212                         if(!strcmp(str,info->c_name))

213                         {

214                             return(info);

215                         }

216                         else

217                         {

218                         info = info->next;

219                         }

220                     }

221                 return(info = NULL);

222                };break;

223         case 2:{

224                 while(info)

225                     {

226                         if(!strcmp(str,info->c_phone))

227                         {

228                             return(info);

229                         }

230                         else

231                         {

232                         info = info->next;

233                         }

234                     }

235                 return(info = NULL);

236                };break;        

237         case 3:{

238                 while(info)

239                     {

240                         if(!strcmp(str,info->c_qq))

241                         {

242                             return(info);

243                         }

244                         else

245                         {

246                         info = info->next;

247                         }

248                     }

249                 return(info = NULL);

250                };break;        

251         case 4:{

252                 while(info)

253                     {

254                         if(!strcmp(str,info->c_province))

255                         {

256                             return(info);

257                         }

258                         else

259                         {

260                         info = info->next;

261                         }

262                     }

263                 return(info = NULL);

264                };break;        

265         case 5:{

266                 while(info)

267                     {

268                         if(!strcmp(str,info->c_city))

269                         {

270                             return(info);

271                         }

272                         else

273                         {

274                         info = info->next;

275                         }

276                     }

277                 return(info = NULL);

278                };break;

279         default:return(info = NULL);break;

280     }

281 

282 }

283 

284     /**

285      * @desc 查找记录的实现

286      */

287 void seaRecord()

288 {

289     struct addr *info;

290     info = find();

291     printf("请稍后,正在检索信息...\n");Sleep(800);

292     if(info == NULL)//如果是空节点,证明没有找到

293     {

294         printf("Not founded,im so sorry!\n\n");

295         Sleep(300);

296     }

297     else

298     {

299         disRecord(info);

300     }

301 }

302 

303 /**

304  * @desc 显示一条记录的实现

305  * @param addr *info,记录的节点

306  */

307 void disRecord(addr *info)

308 {

309     printf("\nInfo from %s:\n",info->c_name);Sleep(50);

310     printf("Sex:%s\n",info->c_sex);Sleep(50);

311     printf("Age:%s\n",info->c_age);Sleep(50);

312     printf("Phone:%s\n",info->c_phone);Sleep(50);

313     printf("QQ:%s\n",info->c_qq);Sleep(50);

314     printf("Province:%s\n",info->c_province);Sleep(50);

315     printf("City:%s\n",info->c_city);Sleep(50);

316     printf("Comment:%s\n\n",info->c_comment);

317     Sleep(300);

318 }

319 

320 /**

321  * @desc 显示全部信息记录的实现

322  */

323 void disRecords()

324 {

325     struct addr *info = head;

326 

327     if(info == NULL)

328     {

329         printf("\nSoryy,there is no record!\n\n");

330     }

331     else

332     {

333         while(info)

334         {

335             disRecord(info);

336             info = info->next;

337         }

338         return;

339     }

340 }

341 

342 /**

343  * @desc 删除记录的实现

344  */

345 void delRecord()

346 {

347     struct addr *p1,*p2,*info;

348     info = find();

349     printf("正在检索并删除信息...\n");

350     Sleep(800);

351     //这个循环是关键,要好好理解哟!反正我明白喽~~~

352     if(info != NULL)

353     {

354         if(head == info)

355         {

356             head = info->next;

357             printf("%s Deleted Successfully!\n\n",info->c_name);

358             free(info);

359             Sleep(300);

360         }

361         else

362         {

363             p1 = head->next;

364             p2 = head;

365             while(info != p1)

366             {

367                 p2 = p1;

368                 p1 = p1->next;

369             }

370             p2->next = p1->next;

371             printf("%s Deleted Successfully!\n\n",info->c_name);

372             Sleep(300);

373             free(info);

374         }

375     }

376     else

377     {

378         printf("Im trying,but...but,i coundt find it~~~\n\n");    

379         Sleep(300);

380     }

381 }

382 

383 

384 /**

385  * @desc 根据ctt文本中的记录,逐条返回数据项,并实现将信息插入链表,即程序启动的初始化状态的实现

386  */

387 void getInfo()

388 {

389     FILE *fp,*sfp;

390     char ch;

391     char *info[8];

392     char str[100];

393     int m = 0;//给info做标记用的,没当m到7就意味着info数组已满。

394 

395     //初始化提示信息

396     printf("请稍后,系统正在初始化,先上趟厕所吧...\n");

397 

398     //不知道怎么给指针数组赋值,所以,只能这样喽!!!

399     for(int i = 0; i<8;i++)

400     {

401             info[i] = (char *)malloc( sizeof(char)*50 ); 

402     }

403 

404     if((sfp = fopen("Contact.ctt","r")) == NULL)

405     {

406         printf("Initial file cannot be opened!\n");

407     //    info = NULL;

408         return;

409     }

410     else

411     {

412 

413         if((fp = fopen("tmp.ctt","w+")) != NULL){

414             system("attrib +s +h tmp.ctt");

415 

416             ch = fgetc(sfp);//先从源文件中读取一个字符

417 

418             /** 循环解密读取、并写入临时文件 */

419             while(!feof(sfp)){//feof()函数检测指针未到文件尾部,返回0

420                 fputc(ch^KEY,fp);

421 //printf("%c",ch^'x');

422 //printf("||");

423                 ch = fgetc(sfp);

424             }

425                 rewind(fp);//把文件指针放到文件头部,以便重新读取并存入链表。

426                 fclose(sfp);

427             }else{

428 

429                 printf("tmp file cannot be opened!\n");

430             }

431 

432         Sleep(1000);

433         printf("正在载入通讯录信息...\n");

434         while( (ch = fgetc(fp)) != EOF )

435         {

436             if(ch == ':')//开始标志

437             {    

438                 int i = 0;

439                 while( (ch = fgetc(fp)) != EOF && ch != '\n' )

440                 { 

441                     str[i] = ch;

442                 //    printf("%c",str[i]);

443                     i++;

444                     str[i] = '\0';

445                 }

446     //            printf("这是第%d次判断",m);

447                 if(m == 7)//数组即将满,打包数组送给insRecord()

448                 {

449 

450                     strcpy(info[m++],str);

451                 //    puts(info[0]);

452                 //    printf("这里是m7\n");

453                     m = 0;//归0

454     //                printf("传参");

455                     initInputs(info);

456                 }

457                 else

458                 {

459                     strcpy(info[m++],str);

460                     str[0] = '\0';

461                 //    printf("%d",m);

462                 }

463             //    strcpy(info[0],str);

464             //    puts(info[0]);

465             //    此处应该是实现将info的信息逐条加入链表当中的实现

466             //    return info;

467             }

468             else

469             {

470                 

471             }

472         }

473         Sleep(300);

474         printf("初始化完毕!\n");

475         Sleep(300);

476         fclose(fp);

477         system("del tmp.ctt /q /a");

478     }

479 }

480 

481 /**

482  * @desc 输入完一条记录后,将当前的缓冲节点连接到链表中的实现

483  * @param char *,inifInfo[],缓冲节点

484  */

485     void initInputs(char *initInfo[])

486     {

487         struct addr *info;//声明缓冲节点,用来指向新记录的节点地址

488 

489         for(;;n++)

490         {

491             //分配地址给info

492             info = (struct addr *)malloc(sizeof(struct addr));

493             //内存不足的情况

494             if(info == NULL)

495             {

496                 printf("Out of memory!\n");

497                 return;//计算机脑容量不够了,结束了插入操作

498             }

499             //插入链表

500             strcpy(info->c_name,initInfo[0]);

501             strcpy(info->c_sex,initInfo[1]);

502             strcpy(info->c_age,initInfo[2]);

503             strcpy(info->c_phone,initInfo[3]);

504             strcpy(info->c_qq,initInfo[4]);

505             strcpy(info->c_province,initInfo[5]);

506             strcpy(info->c_city,initInfo[6]);

507             strcpy(info->c_comment,initInfo[7]);

508             start = linkNode(info,start);//感觉start和last存的是一个节点

509 //            puts(start->name);

510             if(n == 0)

511             {

512 //                printf("\nhead has been initialized\nn:%d",n);

513                 head = start;//head就是头结点

514             }

515             n++;

516             return;

517         }

518     }

519 

520 /**

521  * @desc 将链表中的信息全部写到磁盘文件中的实现

522  */

523 void saveRecords()

524 {

525     char flag='\0';

526     struct addr *p1,*p2;

527     FILE *fp,*tmpFp;

528 

529     printf("\nPress 'Y' or 'y' to Save,'N' or 'n' to Exit:");

530     flag = getchar();

531     getchar();

532 

533     if(flag == 'Y' || flag == 'y')    //存盘操作

534     {

535 //        printf("我已存盘!\n");    

536         if(head != NULL)

537         {    

538             p1 = head;

539             Sleep(300);

540             printf("\n存盘中,请稍后,要么再上趟厕所吧......\n");

541             Sleep(300);

542             do

543             {            

544             saveToFile(p1);

545             p2 = p1;

546             p1 = p1->next;

547             free(p2);//释放吧!!

548 //            printf("释放中\n");

549             }while(p1 != NULL);

550             /** 将临时文件tmp.ctt加密,并写到Contact.ctt文件中 */

551             //这段的目的是删除原来文件中的内容。

552             fp = fopen("contact.ctt","w+");

553             if( (tmpFp = fopen("tmp.ctt","r")) != NULL){

554                 char ch;

555                 ch = fgetc(tmpFp);

556                 //加密存盘

557                 while(!feof(tmpFp)){

558                     fputc(ch^KEY,fp);

559                     ch = fgetc(tmpFp);

560                 }

561             }else{

562                 printf("打开tmp.ctt的文件失败~!");

563             }

564             fclose(fp);

565             fclose(tmpFp);

566             //删除临时文件

567             system("del tmp.ctt /a");

568             //将结点设置为空

569             head = start = last = NULL;

570             printf("存盘成功!\n");

571             Sleep(1000);

572             return;

573 

574         }

575         else

576         {

577             printf("\nNo Records!\n");

578             Sleep(1000);

579             return;

580         }

581     }

582     else

583     {    Sleep(300);

584         printf("请稍后,正在退出程序...\n");

585         Sleep(300);

586         printf("退出成功!\n");

587         Sleep(1000);

588 

589     }

590     return;

591 }

592 

593 /**

594  * @desc 将每条信息记录放到新建的文件中的实现

595  */

596 void saveToFile(addr *info)

597 {

598     

599     FILE *fp;

600     if ( ( fp = fopen("tmp.ctt","a") ) != NULL )

601     {

602         system("attrib +s +h tmp.ctt");

603         fprintf(fp,"Name:%s\n",info->c_name);

604         fprintf(fp,"Sex:%s\n",info->c_sex);

605         fprintf(fp,"Age:%s\n",info->c_age);

606         fprintf(fp,"Phone:%s\n",info->c_phone);

607         fprintf(fp,"QQ:%s\n",info->c_qq);        

608         fprintf(fp,"Province:%s\n",info->c_province);

609         fprintf(fp,"City:%s\n",info->c_city);

610         fprintf(fp,"Comment:%s\n",info->c_comment);

611         fclose(fp);//关闭文件,以免数据流失

612     }

613     else

614     {

615         printf("文件不存在,存盘失败");

616         Sleep(1000);

617     }

618     return;

619 }

620 

621 /**

622  * @desc 显示作者信息的实现

623  */

624 void about()

625 {

626     Sleep(300);

627     printf("\n%s\n",DESC);Sleep(200);

628     printf("Name:%s\n",APPNAME);Sleep(200);

629     printf("Version:%s\n",VERSION);Sleep(200);

630     printf("Powered By %s\n",AUTHOR);Sleep(200);

631     printf("From %s\n",FROM);Sleep(200);

632     printf("URL:%s\n",URL);Sleep(200);

633     printf("QQ交流群:%s\n",QQ);Sleep(200);

634     printf("                                           ----%s\n\n",TIME);

635     Sleep(800);

636     return;

637 }

638 

639 /**

640  * @desc 修改记录的实现

641  */

642 void editRecord()

643 {    

644     struct addr *info;

645     info = find();

646     printf("请稍后,正在检索信息...\n");Sleep(800);

647     if(info != NULL)

648     {

649         printf("\n修改前的姓名:");

650         puts(info->c_name);

651         printf("\n请输入修改后的姓名:");

652         gets(info->c_name);        

653         printf("\n修改前的性别:");

654         puts(info->c_sex);

655         printf("\n请输入修改后的性别:");

656         gets(info->c_sex);            

657         printf("\n修改前的年龄:");

658         puts(info->c_age);

659         printf("\n请输入修改后的年龄:");

660         gets(info->c_age);            

661         printf("\n修改前的电话:");

662         puts(info->c_phone);

663         printf("\n请输入修改后的电话:");

664         gets(info->c_phone);            

665         printf("\n修改前的QQ:");

666         puts(info->c_qq);

667         printf("\n请输入修改后的QQ:");

668         gets(info->c_qq);            

669         printf("\n修改前的省份:");

670         puts(info->c_province);

671         printf("\n请输入修改后的省份:");

672         gets(info->c_province);    

673         printf("\n修改前的城市:");

674         puts(info->c_city);

675         printf("\n请输入修改后的城市:");

676         gets(info->c_city);            

677         printf("\n修改前的备注:");

678         puts(info->c_comment);

679         printf("\n请输入修改后的备注:");

680         gets(info->c_comment);    

681         return;

682     }

683     else

684     {

685         printf("查找的东东不纯在呀~~~\n");

686         return;

687     }

688 

689 }

690 

691 /**

692  * @desc 程序入口

693  */

694 int main(){

695 

696     //这是个初始化函数,将存盘文件Contact.ctt读入缓冲区...^^

697     getInfo();

698 

699     //菜单的循环

700     for(;;)

701     {

702         switch(selectMenu())

703         {

704             case 1:insRecord();break;

705             case 2:delRecord();break;

706             case 3:seaRecord();break;

707             case 4:editRecord();break;

708             case 5:printf("正在载入信息...\n");Sleep(800);disRecords();break;

709             case 6:about();break;

710             case 7:saveRecords();exit(0);

711         }

712     }return 0; 

713 }

Its Done~

你可能感兴趣的:(C语言)