今天过后开始c++的自学之路 !!!
学到现在,给刷到这篇文章的铁子们一点建议。学习是痛苦并快乐过程。
一,不要钻牛角尖,记着,学到后面思路就开阔了,问题就好解决了
二,学习的过程可以穿插着学点数据结构,Linux操作系统,可以让我们暂时摆脱枯燥感,提高学习效率。
三,要明确目标。人生只有一回,不甘心平凡的老去!这是我的驱动力
main.c
#define _CRT_SECURE_NO_WARNINGS
#include "dlist.h"
//枚举,在48行switch语句中case目标代替十进制数字,提高代码的可读性
enum Option
{
Exit,
PushBack,
PushFront,
Insert,
PopBack,
Find,
Modify,
Print
};
//创建菜单
void menu()
{
printf("******************************************************\n");
printf("******* 1.PushBack 2.PushFront ******\n");
printf("******* 3.Insert 4.PopBack ******\n");
printf("********5.Find 6.Modify ******\n");
printf("********7.Print 0.Exit ******\n");
printf("******************************************************\n");
}
int main()
{
//创建哨兵位
contact head = { 0 };
head.prev = &head;
head.next = &head;
LoadContact(&head);//加载文件的函数,和72行的SaveContact(&head)函数相呼应,用来打开之前存储的通讯录文件
int input = 0;
do
{
menu();//创建菜单
printf("Please choose:> ");
while (scanf("%d", &input) == 0)//这循环用来消除输入了不匹配%d的字符(可以再进一步完善)
{
getchar();
}
switch (input)
{
case PushBack:
DListPushBack(&head);//尾插函数
break;
case PushFront:
DListPushFront(&head);//前插函数
break;
case Insert:
DListInsert(&head);//选择插入位置进行插入(前插和尾插可以分装这个函数,可以优化的地方)
break;
case PopBack:
DListPopBack(&head);//尾删函数(还有前删,选择删除等函数可以写,这里就不一一写了)
break;
case Find:
DLstFind(&head);//查找函数
break;
case Modify:
DListModify(&head);//修改函数,先通过查找定位
break;
case Print:
PrintDList(&head);//显示函数
break;
case Exit:
SaveContact(&head);//正常退出后,会生成文件保存数据
exit(0);
default:
printf("Wrong choose,please try again!\n");
}
} while (input);
return 0;
}
SList.c
#define _CRT_SECURE_NO_WARNINGS
#include "dlist.h"
//加载文件的函数
void LoadContact(contact* phead)
{
contact* temp = (contact*)malloc(sizeof(contact));//开辟一块内存,用来存放第一块将要被读取的数据块
assert(temp);//要断言一下,一是语法要求,在编译阶段,fread函数会要求检查temp指针,如果没有判断,会发出警告,也可以用if
FILE* pf = fopen("contact.dat", "r");
if (pf == NULL)
{
perror("LoadContact->open: ");
return;
}
while (fread(temp, sizeof(contact), 1, pf))//fread函数每次成功读取数据都会返回一个unsigned,失败则返回0;
{
/*这个就是带哨兵位双循环链表的精髓,贯穿整个程序,文章头有我画的一个逻辑图*/
contact* tail = phead->prev;
tail->next = temp;
temp->prev = tail;
temp->next = phead;
phead->prev = temp;
temp = (contact*)malloc(sizeof(contact));
assert(temp);
}
}
//创建新节点的(要插入的是数据,封装成一个内存节点)
contact* CreatNewNode()
{
contact* NewNode = (contact*)calloc(1,sizeof(contact));
assert(NewNode);
printf("please input name:> ");
scanf("%s", NewNode->StuContact.name);
printf("please input age:> ");
scanf("%d", &(NewNode->StuContact.age));
printf("please input addr:> ");
scanf("%s", NewNode->StuContact.addr);
printf("please input rec:> ");
scanf("%f", &(NewNode->StuContact.rec));
NewNode->prev = NULL;
NewNode->next = NULL;
return NewNode;
}
//保存通讯录
void SaveContact(contact* phead)
{
FILE* pf = fopen("contact.dat", "w");
if (pf == NULL)
{
perror("LoadContact->open: ");
return;
}
contact* temp = phead;
while (temp->next != phead)
{
temp = temp->next;
fwrite(temp, sizeof(contact), 1, pf);
}
fclose(pf);
pf = NULL;
}
//尾插
void DListPushBack(contact* phead)
{
contact* NewNode = CreatNewNode();
contact* tail = phead->prev;
tail->next = NewNode;
NewNode->prev = tail;
NewNode->next = phead;
phead->prev = NewNode;
}
//显示当前整个通讯录
void PrintDList(contact* phead)
{
contact* temp = phead;
printf("%-15s\t%-8s\t%-20s\t%-8s\n", "name", "age", "addr", "rec");
while (temp->next != phead)
{
temp = temp->next;
printf("%-15s\t", temp->StuContact.name);
printf("%-8d\t", temp->StuContact.age);
printf("%-20s\t", temp->StuContact.addr);
printf("%-8.2f\t", temp->StuContact.rec);
printf("\n");
}
}
//前插
void DListPushFront(contact* phead)
{
contact* NewNode = CreatNewNode();
contact* temp = phead->next;
temp->prev = NewNode;
NewNode->prev = phead;
NewNode->next = temp;
phead->next = NewNode;
}
//显示当前位置的通讯录信息,用static修饰了,只在当前文件可见
static void CurPrint(contact* cur)
{
printf("%-15s\t%-8s\t%-20s\t%-8s\n", "name", "age", "addr", "rec");
printf("%-15s\t", cur->StuContact.name);
printf("%-8d\t", cur->StuContact.age);
printf("%-20s\t", cur->StuContact.addr);
printf("%-8.2f\t", cur->StuContact.rec);
printf("\n");
}
//查找数据(还可以完善下,可以按要求查找,比如选择姓名,地址等)
contact* DLstFind(contact* phead)
{
char name[MAX_NAME] = { 0 };
contact* temp = phead;
do
{
temp = phead;
printf("please input the name you want to find:> ");
scanf("%s", name);
assert(name);
while (temp->next != phead)
{
temp = temp->next;
if (!strcmp(temp->StuContact.name, name))
{
CurPrint(temp);
return temp;
}
}
printf("the name NOT FOUND\n");
printf("If you want to continue, enter 1. To end, enter 0: ");
int input = 0;
while (scanf("%d", &input) == 0)
{
getchar();
}
switch (input)
{
case 1:
break;
case 0:
temp = NULL;
break;
default:
printf("Wrong choose,please try again!\n");
break;
}
} while (temp);
return temp;
}
//插入数据函数
void DListInsert(contact* phead)
{
contact* temp = DLstFind(phead);
if (!temp)
{
return;
}
printf("find success!to insert\n");
contact* NewNode = CreatNewNode();
contact* temp_prev = temp->prev;
temp_prev->next = NewNode;
NewNode->prev = temp_prev;
NewNode->next = temp;
temp->prev = NewNode;
}
//尾删
void DListPopBack(contact* phead)
{
contact* tail = phead->prev;
if (tail == phead)
{
printf("DList is NULL\n");
return;
}
contact* tail_prev = tail->prev;
phead->prev = tail_prev;
tail_prev->next = phead;
free(tail);
tail = NULL;
printf("delete success!\n");
}
//修改
void DListModify(contact* phead)
{
contact* temp = DLstFind(phead);
if (!temp)
{
return;
}
printf("find success!to insert\n");
printf("please input name:> ");
scanf("%s", temp->StuContact.name);
printf("please input age:> ");
scanf("%d", &(temp->StuContact.age));
printf("please input addr:> ");
scanf("%s", temp->StuContact.addr);
printf("please input rec:> ");
scanf("%f", &(temp->StuContact.rec));
}
DList.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME 15
#define MAX_ADDR 20
typedef struct stu
{
char name[MAX_NAME];
int age;
char addr[MAX_ADDR];
float rec;
}StuInfo;
typedef struct contact
{
StuInfo StuContact;
struct contact* prev;
struct contact* next;
}contact;
void DListPushBack(contact*phead);
void PrintDList(contact* head);
void SaveContact(contact* phead);
void LoadContact(contact* phead);
void DListPushFront(contact* phead);
contact* DLstFind(contact* phead);
void DListInsert(contact* phead);
void DListPopBack(contact*phead);
void DListModify(contact* phead);