c语言项目实战 —— 图书管理系统
图书管理系统
- 目的
- 总体功能分析
- 各模块功能简要分析
- 1,图书借出模块
- 2,图书归还模块
- 3,图书上架模块
- 4,图书下架模块
- 5,查找图书模块
- 6,退出系统模块
- 功能实现
- 1,建立相关类及属性
- 2,系统选择菜单实现
- 3,图书上架功能实现
- 4,图书下架功能实现
- 5,查找图书功能实现
- 6,借书功能实现
- 7,还书功能实现
- 8,主函数功能实现
- 系统运行测试结果
- 系统难点
- 完整代码
github仓库: 项目代码
目的
使用C语言来开发一个较为完整的图书管理系统,让读者全面掌握使用C语言开发应用程序的流程。
总体功能分析
只有进行了详细的分析后,才能使后续的开发过程按部就班地进行,不至于出现顾此失彼甚至出错的情况。
实用的图书馆管理系统应该至少包括以下功能。
- (1)上架:新进图书及基本信息输入。
- (2)下架:旧图书及基本信息初除。
- (3)查找:查询要借阅的图书信息。
- (4)借书:实现用户办理借书手续。
- (5)还书:实现用户办理还书手续。
系统以菜单方式工作可以使界面友好,易于操作。用户可以对本系统进行自己需要的查询或修改操作,如根据用户的需求自动进行添加操作、初除操作、借还操作,也可以查找所要的图书、查阅图书的详细资料、查阅读者的详细资料,最后在屏幕中清晰完整地显示结果,方便使用者对图书借阅的操作,提高准确性,达到亊半功倍的效果。
系统采用的是自顶向下、层次化的模块结构,把一个大的模块逐步分解成较小的相对简单的模块。整体功能模块见下图:
各模块功能简要分析
1,图书借出模块
该模块主要完成借书的操作。在借书时,需要输入读者学号和书号。读者借完书后,相应的馆藏图书的数量会减少。
2,图书归还模块
该模块主要完成还书的操作。在还书时,需要输入读者学号和书号。读者还完书后,相应的馆藏图书的数量会增加
3,图书上架模块
该模块主要完成图书上架的基本操作,即新增图书的入库和显示操作。
4,图书下架模块
该模块主要完成图书下架的基本操作,即馆藏图书的初除下架和显示操作。
5,查找图书模块
该模块主要完成图书查找的基本操作,即可以根据书名在馆藏图书中进行查找和显示操作。
6,退出系统模块
退出系统功能。
功能实现
1,建立相关类及属性
在此采用结构体来存储这些数据类型。首先需要建立一个图书类、图书数据库类、读者类以及读者数据库类,并定义图书和读者的各种属性,以及声明各功能函数,具体代码参见:“1,相关类及属性.txt”
2,系统选择菜单实现
用户根据需要,输入不同的数字来选择相应功能,具体代码参见: “2,菜单实现.txt”
3,图书上架功能实现
图书上架是指将书籍信息添加到图书馆藏库存中,具体代码参见: “3,上架.txt”
4,图书下架功能实现
图书下架是指将指定的图书从馆藏数据中初除,具体代码参见:“4,下架.txt”
5,查找图书功能实现
选择查找图书菜单,根据要求输入相关信息,可实现图书的查找功能,具体代码参见:“5,查找图书.txt”
6,借书功能实现
选择借书菜单,输入相关信息,实现借书功能,具体代码参见:“6,借书.txt”
7,还书功能实现
书籍阅读完毕需要及时归还。选择还书菜单,输入要归还书籍的书号,即可实现还书功能。还书成功后,图书库存将增加,具体代码参见:“7,还书.txt”
8,主函数功能实现
主函数的主要功能是调用系统选择函数,实现图书管理功能。具体代码参见:“8,主函数.txt”
系统运行测试结果
具体实现演示就不再展示。
系统难点
- 功能的划分
- 指针与链表的操作,常常会遇到不知道链表的指针应该如何操作的问题。
完整代码
系统实现完整代码如下:
#include <stdlib.h>
#include <stdio.h>
//#include <conio.h>
#include "math.h"
//#define m 1
struct Date /*日期结构*/
{ int m_nYear; /*年*/int m_nMonth; /*月*/ int m_nDay; /*日*/
};struct Reader /*读者结构*/
{char num[20]; /*借书证号*/struct Date bro; /*借出时间*/ struct Date back; /*归还时间*/
};struct Book /*书本结构*/
{int m_iBook_Number; /*对应书本号*/ char m_strTitle[150]; /*书名*/char m_strWroter[150]; /*作者*/ int m_nMoreNum; /*当前在架册数*/ int m_nTotalHoldNum; /*馆藏册数*/ char m_strComment[300]; /*图书简介*/ struct Reader reader[200];
};
struct Info /*借书信息结构*/
{struct Info *m_pParentPoint; /*前驱结点*/ struct Book *m_pBookInfo; /*对应书本的信息*/ struct Info *m_pSun; /*后继结点*/};struct Book *InputNode();
struct Info *Search(struct Info *bth,int x,int *k,int *flag);/*查找图书*/
struct Info *Insert_BookInfo(struct Info *bth);/*图书上架*/
struct Info *Delete_BookInfo(struct Info *bth);/*图书下架*/
void Output_BookInfo(struct Info *bth);/*打印输出书本信息*/
void Borrow_TheBook(struct Info *bth);/*图书出借*/
void TurnBack_TheBook(struct Info *bth);/*图书归还*/
char Select_Menu();/*图书馆管理系统主菜单*/
struct Info *Search(struct Info *bth,int x,int *k,int *flag)
{struct Info *p=NULL;/*当前工作指针*/p=bth; /*每次查询前,将工作指针指向双向链表头部结点*/*flag=0; /*是否查找到指定书个号的标志,初始化置为0*/while(p){if(p->m_pBookInfo->m_iBook_Number==x){/*找到相同的书号,置找到的标志*/*flag = 1;return p;}else{/*未找到相同的书号,置未找到标志*/*flag = 0;}if(p->m_pSun!=NULL){p = p->m_pSun;/*没到双向链表的尾部时,向后移动当前指针*/}else{break;/*到达链表尾部,跳出循环*/}}return bth;
}
struct Book *InputNode()
{struct Book *p=NULL;int i;p=(struct Book *)malloc(sizeof(struct Book)); /*分配内存*/system("cls");/*清屏*/fflush(stdin); /*清除以前的输入*/printf("\n\t请输入书名: "); gets(p->m_strTitle);/*从键盘取得书名*/printf("\n\t请输入作者: ");gets(p->m_strWroter);/*从键盘取得厂家名*/printf("\n\t请输入当前在架数量: ");scanf("%d",&p->m_nMoreNum);/*从键盘取得当前在架数量*/printf("\n\t请输入库存数量: ");scanf("%d",&p->m_nTotalHoldNum);/*从键盘取得当前库存数量*/fflush(stdin);printf("\n\t请输入图书简介: ");/*从键盘取得个图书内容简要介绍*/gets(p->m_strComment);/*以上从输入输出设备取得要求的信息*/for(i=0;i<20;i++)(p->reader[i]).num[0]='\0';/*初始化书个结构成员的相关读者指针内容为空*/return(p); /*返回成功插入的一个图书信息*/
}
struct Info *Insert_BookInfo(struct Info *bth)
{int flag,j,k,t;int y,x,z;struct Info *p=NULL,*q=NULL,*u=NULL,*s=NULL;struct Book *r=NULL,*l=NULL;system("cls");/*清屏*/printf("\n\t请输入你想上架的图书编号: ");scanf("%d",&x);/*取书号*/ q=Search(bth,x,&k,&flag);/*查找上架的书是否已经上架,返回已经找到的书的信息*/if(flag==1) {/*查找成功,存在此书*/printf("\n\t当前存在这个图书%d个,您想再增加一个<<%s>>书?(y/n)\n",q->m_pBookInfo->m_nTotalHoldNum,q->m_pBookInfo->m_strTitle);z=getch();if(z=='y'||z=='Y') {/*确认上架另一个商品*/printf("\n\t个馆此书一共有: %d 个",q->m_pBookInfo->m_nTotalHoldNum);printf("\n\t并且有: %d 个在图书馆中内未借出.",q->m_pBookInfo->m_nMoreNum);q->m_pBookInfo->m_nTotalHoldNum++;q->m_pBookInfo->m_nMoreNum++; printf("\n\t上架后一共有: %d 个",q->m_pBookInfo->m_nTotalHoldNum);printf("\n\t上架后当前有: %d 个在图书馆中.",q->m_pBookInfo->m_nMoreNum);}return(bth); }r=InputNode(bth); /*成功插入书的信息,指针r存放刚刚插入的书个*/if(bth==NULL) {/*指针bth为空时,表示当前链表为空,此时需要单独处理,即链表头内存分配*/bth=p=(struct Info *)malloc(sizeof(struct Info));/*申请内存*/r->m_iBook_Number = x;/*将书号存入书的信息结构体*/p->m_pParentPoint= NULL;/*前驱结点置空*/p->m_pSun=NULL;/*后继结点置空*/p->m_pBookInfo=r;return(p); /*返回新成功插入的书个结点*/}else{/*说明已经有头指针,则在此开始处理新插入的结构体指针*/p=NULL; p=bth;while(p->m_pSun!=NULL){p = p->m_pSun;/*当后继结点不为空时,表示还未到链表尾部*/}/*当循环结束后,p指向的就是最后一个结点*/q=(struct Info *)malloc(sizeof(struct Info));/*申请内存*/r->m_iBook_Number = x;/*将书号存入书的信息结构体*/p->m_pSun = q; /*双向链表的前驱与后继结点链接*/q->m_pParentPoint= p;/*前驱结点置为p*/q->m_pSun=NULL;/*后继结点置空,相当于电线接地*/q->m_pBookInfo=r;/*指向新插入的图书的信息结构体*/}return(bth);
}
struct Info *Delete_BookInfo(struct Info *bth)
{int flag,j,k,t;int x,y;struct Info *u=NULL,*s=NULL,*p=NULL,*q=NULL;struct Book *Bookinfo=NULL;struct Info *BookLeftPoint=NULL;/*前驱结点*/struct Info *BookRightPoint = NULL;/*后继结点*/system("cls");/*清屏*/printf("\n\t请输入你想下架的书个号: ");scanf("%d",&x);/*接受输入*/q=Search(bth,x,&k,&flag);/*查找指定的书是否存在*/ if(flag==0) { /*图书不存在是,直接输出消息并返回*/printf("\n\t这个图书不存在!\n"); return(bth);} else{if(q==NULL){printf("未知错误");return bth;/*确保当前工作指针是有效的,防止出现非法操作*/}else{Bookinfo=q->m_pBookInfo;printf("\n\t想下架的书的信息: "); printf("\n\t书名: %s",Bookinfo->m_strTitle); printf("\n\t作者: %s",Bookinfo->m_strWroter);printf("\n\t当前在架数量: %d",Bookinfo->m_nMoreNum);printf("\n\t库存数量: %d",Bookinfo->m_nTotalHoldNum);printf("\n\t图书简介: %s\n",Bookinfo->m_strComment);/*删除指定的书的信息的思路:设当前找到的链表中的结点是q,它的前驱为q-1,后继为q+1,则,只需要作三部操作:1.将要删除的结点的后继结点的前驱指针域指向要删除的结点的前驱结点2.将要删除的结点的前驱结点的后继指针域指向要删除的结点的后继结点3.释放要删除的结点的书的信息域的内存,释放要删除的结点的内存需要注意两个特殊结点:要删除的结点是首结点或尾结点时,需要分别判断处理*/if(q->m_pParentPoint!=NULL && q->m_pSun!=NULL){/*夹在链表中间的结点*/BookLeftPoint = q->m_pParentPoint;/*要删除的结点的前驱指向赋给前驱结点指针变量*/BookRightPoint = q->m_pSun;/*要删除的结点的后继指向赋给后继结点的指针变量*/BookLeftPoint->m_pSun = BookRightPoint;/*将后继结点指针指向的地址作为前驱结点中新后继域*/BookRightPoint->m_pParentPoint = BookLeftPoint;/*将后继结点指向的前驱域设定为要删除的结点的前驱结点*/q->m_pParentPoint = NULL;q->m_pSun = NULL;free(q->m_pBookInfo);/*先将书的信息结构体的内存释放*/q->m_pBookInfo = NULL;/*使指针指向安全地址*/free(q);/*将要删除的借还书信息结构体指针使用的内存空间释放*/q = NULL;/*要习惯将动态分配的内存在使用后动态释放,并将指针域指向空*/return bth;/*返回首结点*/}else if(q->m_pParentPoint==NULL){/*首结点的前驱为空,这里处理首结点删除操作*/if(q->m_pSun==NULL){/*前后指针域均为空时,说明只有一个结点,此时只需要将此结点删除*/free(q->m_pBookInfo);q->m_pBookInfo = NULL;free(q);q = NULL;return q;}bth = q->m_pSun;bth->m_pParentPoint = NULL;/*要删除的结点的后继指向赋给后继结点的指针变量*/BookRightPoint = q;BookRightPoint->m_pParentPoint = NULL;/*将链表中指向首结点的后继指针的前驱指针域置为空,表明是新的首结点*/BookRightPoint->m_pSun = NULL;/*将链表中指向首结点的后继指针的前驱指针域置为空,表明是新的首结点*/free(BookRightPoint->m_pBookInfo);/*先将书的信息结构体的内存释放*/BookRightPoint->m_pBookInfo = NULL;/*使指针指向安全地址*/free(BookRightPoint);/*将要删除的借还书信息结构体指针使用的内存空间释放*/BookRightPoint = NULL;/*要习惯将动态分配的内存在使用后动态释放,并将指针域指向空*/return bth;/*返回首结点*/}else if (q->m_pSun==NULL){/*尾结点的后继结点为空,这里处理尾结点的删除操作*/BookLeftPoint = q->m_pParentPoint; /*将要删除的结点即尾结点的前驱域保存到前驱指针变量中*/BookLeftPoint->m_pSun = NULL;/*将要删除的结点的前驱结点与链表断开,前驱结点作为新的尾结点*/q->m_pParentPoint = NULL;free(q->m_pBookInfo);/*先将书的信息结构体的内存释放*/q->m_pBookInfo = NULL;/*使指针指向安全地址*/free(q);/*将要删除的借还书信息结构体指针使用的内存空间释放*/q = NULL;/*要习惯将动态分配的内存在使用后动态释放,并将指针域指向空*/return bth;/*返回首结点*/}}}
}void Output_BookInfo(struct Info *bth)
{struct Info *q=NULL;struct Book *p=NULL;int k=0;int x=0;int flag=0;system("cls");printf("\n\t请输入你想查找的书个号: ");scanf("%d",&x);q=Search(bth,x,&k,&flag); if(flag==1){p=q->m_pBookInfo;printf("\n\t书名: %s",p->m_strTitle); printf("\n\t作者: %s",p->m_strWroter);printf("\n\t当前在架数量: %d",p->m_nMoreNum);printf("\n\t库存数量: %d",p->m_nTotalHoldNum);printf("\n\t图书简介: %s\n",p->m_strComment);}else printf("\n\t这个图书不存在!");
}
void Borrow_TheBook(struct Info *bth)
{struct Info *q=NULL;struct Book *p=NULL;int i,k, x, flag,t;system("cls");/*清屏*/printf("\n\t请输入你想借的书个号: ");/*打印消息*/scanf("%d",&x);/*接受输入*/q=Search(bth,x,&k,&flag); /*查找书个*/if(flag==1) {p=q->m_pBookInfo;printf("\n\t借出这个图书 ?(y/n)");printf("\n\t书名: %s",p->m_strTitle);printf("\n\t作者: %s",p->m_strWroter);printf("\n\t当前在架数量: %d",p->m_nMoreNum);printf("\n\t库存数量: %d",p->m_nTotalHoldNum);printf("\n\t图书简介: %s\n",p->m_strComment);t=getch();if(t=='y'||t=='Y'){/*确认借这个图书*/if( (p->m_nMoreNum)==0) printf("\n\t对不起,图书已经全部借出...");else{system("cls");for(i=0;i<20;i++) if( (p->reader[i]).num[0]=='\0') break;printf("\n\t请输入借书证号: "); scanf("%s",(p->reader[i]).num);printf("\n\t请输入借出的日期: "); printf("\n\t年: ");scanf("%d",&((p->reader[i]).bro.m_nYear));printf("\t月: ");scanf("%d",&((p->reader[i]).bro.m_nMonth));printf("\t日: ");scanf("%d",&((p->reader[i]).bro.m_nDay));printf("\n\t请输入归还日期: ");printf("\n\t年: ");scanf("%d",&((p->reader[i]).back.m_nYear));printf("\t月: ");scanf("%d",&((p->reader[i]).back.m_nMonth));printf("\t日: ");scanf("%d",&((p->reader[i]).back.m_nDay));p->m_nMoreNum--; printf("\n\t成功借到个图书.");}}}else printf("\n\t这个图书不存在!");
}
void TurnBack_TheBook(struct Info *bth)
{struct Info *q=NULL;struct Book *p=NULL;int i,k, x, flag,t,j;int year,month,day,d;float pay;char temp[20];system("cls");/*清屏*/printf("\n\t请输入归还的书个号: ");scanf("%d",&x);q=Search(bth,x,&k,&flag); /*书个查找*/ if(flag==1){/*找到个图书*/p=q->m_pBookInfo;printf("\n\t你想归还这个图书 ?(y/n)");printf("\n\t书名: %s",p->m_strTitle);printf("\n\t作者: %s",p->m_strWroter);printf("\n\t当前在架数量: %d",p->m_nMoreNum);printf("\n\t库存数量: %d",p->m_nTotalHoldNum);printf("\n\t图书简介: %s\n",p->m_strComment);t=getch();/*接受选择*/if(t=='y'||t=='Y'){/*确认归还这个图书*/if( (p->m_nMoreNum) >=(p->m_nTotalHoldNum) )printf("\n\t想再上架一个图书吗 ??\n");else{system("cls");printf("\n\t请输入借书证号: ");scanf("%s",temp);j=0;for(i=0;i<20;i++){if(! (strcmp(temp,(p->reader[i]).num))) {j=1;break;} }if(j==0) {printf("\n\t你不能借这个图书。");return;} printf("\n\t今天是:"); printf("\n\t年: ");scanf("%d",&year);printf("\t月: ");scanf("%d",&month);printf("\t日: ");scanf("%d",&day);d=0;if(year<(p->reader[i]).back.m_nYear) d=1; if(year<=(p->reader[i]).back.m_nYear && month<(p->reader[i]).back.m_nMonth) d=1;if(year<=(p->reader[i]).back.m_nYear && month<=(p->reader[i]).back.m_nMonth && day<(p->reader[i]).back.m_nDay) d=1;if(d==0){/*超过还书日期,在此还书*/system("cls");pay=(year-(p->reader[i]).back.m_nYear)*365+(month-(p->reader[i]).back.m_nMonth)*30+(day-(p->reader[i]).back.m_nDay);printf("\n\t你的借书日期是: %d-%d-%d",(p->reader[i]).bro.m_nYear,(p->reader[i]).bro.m_nMonth,(p->reader[i]).bro.m_nDay); printf("\n\t你的还书日期是: %d-%d-%d之前",(p->reader[i]).back.m_nYear,(p->reader[i]).back.m_nMonth,(p->reader[i]).back.m_nDay);printf("\n\t今天是 %d-%d-%d",year,month,day);printf("\n\n\t因此你超出借期,");printf("\n\t应该支付%2.1f 元罚款.",0.1*pay); }(p->reader[i]).num[0]='\0'; p->m_nMoreNum++; printf("\n\t你已经归还了这个图书.");}}}else printf("\n\t你不能归还不存在的一个图书!!!"); }char Select_Menu()
{/*主菜单显示函数*/system("cls");printf("/******************************************\\\n");printf("* *\n");printf("* 图 书 馆 管 理 系 统 *\n");printf("* 主菜单 *\n");printf("* *\n");printf("* 1. 图书上架 *\n");printf("* 2. 图书下架 *\n");printf("* 3. 查找图书 *\n");printf("* 4. 图书出借 *\n");printf("* 5. 图书归还 *\n");printf("* 6. 退出系统 *\n"); printf("* *\n");printf("* 请选择菜单项:(1~6) *\n");printf("\\******************************************/\n");return getch();
}void main()
{char c,t;int flag,p=1;struct Info *bth=NULL;while(1){c=Select_Menu(); printf("您选择了:%c",c);getch();switch(c) {case '1': bth=Insert_BookInfo(bth);/*图书上架*/break;case '2': bth=Delete_BookInfo(bth);/*图书下架*/break;case '3': Output_BookInfo(bth);/*查找图书*/break;case '4': Borrow_TheBook(bth);/*图书出借*/break;case '5': TurnBack_TheBook(bth);/*图书归还*/break;case '6':case '0': system("cls");printf("\n\t你想退出系统 ?(y/n)");t=getch();if(t=='y'||t=='Y') exit(0);break;}printf("\n\t按任意键返回主菜单....");getch();}
}
c语言项目实战 —— 图书管理系统相关推荐
- C语言项目实战——学生成绩系统管理
C语言项目实战 --学生成绩管理系统 项目开发基本流程 可行性分析和项目开发计划 技术可行性:软硬件.技术人员条件.项目是否能实现 经济可行性:成本估算.开发时间.经济效益评估,看这个项目是否有开发价 ...
- Java项目实战---歌曲管理系统
Java项目实战-歌曲管理系统 声明:本人仅整理了代码,方便大家进行调试优化,功能上还存在很多纰漏,欢迎大家评论区讨论 代码原地址放于文章末尾 一.实验目的: 掌握类的定义,JAVA应用程序的设计与实 ...
- C语言课程设计-图书管理系统
实训项目名称:图书管理系统的设计与实现 1.实训目的 开发一个小型的图书管理应用软件,使用该软件可以实现图书信息的登记.浏览.借书.还书.删除和更新等操作.通过该系统的实现可以了解C++连接数据库的原 ...
- [开源] C语言项目实战 - 虚拟鼠标 - VirtualMouse
C语言项目实战 - 虚拟鼠标 - VirtualMouse 目录 关于软件 软件介绍 使用帮助 项目介绍 源码及软件下载 知识点扫描 热键的使用 鼠标事件的模拟 字体的选用 开机自启动的设置 为软件添 ...
- 项目的数据存储c语言,C语言项目实战项目8__项目中学生数据的存储与重用.ppt
C语言项目实战项目8__项目中学生数据的存储与重用 项目8 技能目标 能用fopen函数和fclose函数打开和关闭文件 能正确地读写文件 能用文件定位函数对文件进行正确的定位操作 能用格式化读写函数 ...
- javaWeb项目之图书管理系统(附视频讲解)
javaWeb项目之图书管理系统(附视频讲解) 视频播放地址:javaWeb图书系统 本系统为"Swing项目之图书管理系统"(此源码已共享)的Web版,网页框架用采用EasyUI ...
- C语言项目实战:24点游戏计算器(基于结构体、指针、函数、数组、循环等知识点)
文章目录 C语言项目实战:24点游戏计算器(基于结构体.指针.函数.数组.循环等知识点) 前言:24点游戏计算器的规则如下 一.项目的创建标 1.选择项目 2.输入项目名称和路径 3.创建头文件Mai ...
- c语言课程设计图书管理系统
数据结构c语言课程设计 图书管理系统 我做的是百度文库的第28题,目前没有报错,正常运行,但是还有一点小bug.代码很多地方写的不是很好,请多多包涵. 账号1,密码1,为管理员账号:其他账号2,3,4 ...
- 学校图书管理系统基于c语言源代码,基于C语言的学校图书管理系统参考.doc
基于C语言的学校图书管理系统参考 本科学生毕业论文(设计) 题目(中 文):基于C语言的学校图书管理系统(英 文):School Library Management System Based on ...
最新文章
- repo同步代码_iTOP-4412开发板android4.0代码下载和编译
- nginx 同一个端口支持 http https_Nginx
- jquery 控制模板菜单样式
- 部署superset_ubuntu16下部署apache superset趟坑指南(内有福利)
- php redis.h,swoole安装hredis支持导致php不能加载swoole扩展
- 伤疤好了有黑印怎么办_春藤家长圈|家有二孩,老大老二一起抢东西,家长该怎么办?...
- 防火墙设置导致服务器站点打开,服务器、网站、环境配置全正常网站打不开原来是系统防火墙造成的...
- phantomjs linux java_PhantomJS 在linux上使用
- 使用PSD设计网页页面
- 关于MySQL内存泄露如何排查的一些思路
- Tomcat version 5.5 only supports J2EE 1.2, 1.3, and 1.4 Web modules
- 用CMake编译lua
- Linux之zlog的学习
- IDL简单读写nc文件
- 简述SD卡的工作原理(四)
- PMBOK(第六版) 学习笔记 ——《第十三章 项目相关方管理》
- php+dns+缓存,清理电脑dns缓存方法
- ssh-keygen的使用方法
- 脚本自动ping检测网络情况
- 无线网可拼服务器吗6,当WiFi 6遇到了WiFi 6+,我们的网速真的变快了吗?