C语言: 简易图书管理系统
这只是一个简易的图书管理系统,虽然它有千余行代码,不过终究是个简单基本的东西。
在Linux系统下,用Vim编写,如要在Windows上运行则需要一些改动,主要是一些调用系统函数的改动。如Windows下的cls命令在Linux下是clear,延时所用到的Sleep()函数在Windows和Linux下调用的头文件不同(unistd.h为Linux系统所用,windows.h为Windows系统所用)。在代码已用注释标识,如要在Windows下运行的话,只需要将注释内容交换即可。
个人就简单的管理系统进行的一个扩展和完善:
首先是健壮性,对于输入的数据不符合或非法,笔者都进行了一个判断和对话询问,尽量做到人性化。
其次,使用字符的输入然后对其进行判断和返回值,避免了造成崩溃的情况发生。
充分发挥函数作用,将每一个函数做好分工,方便调试和调用。
界面进行了适当的美化,保证人机的友好交互。
使用了一些实用的扩展功能。
对于一些扩展的说明:
清空输入缓存区方法,比如我们之用使用了回车符确认了某操作,那么下一次使用gets()或其它的函数如会吸收到这个回车符并执行。那么我们如何将这个回车符清掉呢,如我们想要暂停而不要调用系统函数呢,是要写两次getch()么,这样也不美观吧。那么我们在头文件定义下方定义以下内容的宏定义。需要调用时,只需输入Clear_buffer就可以了,当然名称可以自定义。(注意以下内容中的 "\" 是一个连接符,也就是 #define 宏定义是一行定义,而这样不美观,因此使用此来连接语句)
#define Clear_buffer\
{\
char ch;\
while((ch = getchar()) != EOF && ch != '\n');\
}
当然,你也可以使用setbuf();fflush(stdin);
rewind(stdin)等
函数来清空,不过因为编程环境不同,此函数在Linux系统下无效,因此以上的方法为万全之策。
大概就这样吧,上完整代码吧。
// 图书管理系统 V1.0
//
// -by 404NotFound945
//--------------------------------------------
//
// Linux系统下使用Vim编写
// 作者: 404NotFound945
// 时间: 2018/05/10
//
// 注意:
// 若要在DOS内核中运行部分命令需改动
// 如system("clear") > system("cls")
// 需改动部分已用//注明
// 且使用在Windows系统下的命令时代替
//-------------------------------------------- #include <stdio.h>
#include <stdlib.h>//system()函数库
#include <string.h>//strcmp(), strcpy()函数库
#include <unistd.h>//Linux下sleep()函数库
//#include <windows.h>//Windows下Sleep()函数库 #define BN BookNumber//宏定义增加图书的数量
#define RN RealNumber//宏定义存在图书的数量
// 将清空缓存区封装成一个函数方便调用
// 注意:
// 根据C99规定最外层的花括号前必须有空格
// 其中 '\' 为语句连接符 为了解决单行写多个语句的尴尬
#define Clear_buffer\
{\
char ch;\
while((ch = getchar()) != EOF && ch != '\n');\
} int BN; //增加图书的数量使用全局变量方便
int RN = ;//实际库存图书数量 typedef struct books //定义图书结构体
{
char name[];
char isn[];
char author[];
float price;
int number;
}book;
book books[]; void border_x()//x轴边框模板
{
printf("\n\t\t\t -------------------------------------------------\n");
} void border_y()//y轴边框模板
{
printf("\t\t\t |");
} void project()//信息名称模板
{
printf("\n\t\t序号\t\t 名称\t\t ISN\t\t 作者\t\t 价格\t\t 数量\n");
} void info(int n)//信息模板
{
printf("\t\t %2d \t\t %6s \t %6s \t %6s \t %5.2f \t %4d\n", n+, books[n].name, books[n].isn, books[n].author, books[n].price, books[n].number);
} void save()//保存数据
{
FILE *fp;
fp = fopen("book.bin", "wb+");//以可追加数据的方式打开二进制文件
//判断是否写入文件成功
//fwrite 有两种调用方式如下
//fwrite(buf, 1, sizeof(buf), fp) 和 fwirte(buf, sizeof(buf), 1, fp)
//网络收集资料说 区别是前者写入成功返回实际写入的数据个数 后者是返回值 1
//
//疑惑:
// 然而笔者按照此用法运用时,发现并非这样,如下笔者调用的方式是返回值都为 1
// 但是在实际运用中却是返回实际写入数据的个数 RN
if(((fwrite(&RN, sizeof(int), , fp)) == ) && (fwrite(books, sizeof(book), RN, fp) == RN))
printf("写入文件成功.\n\n");
else
{
printf("写入文件失败.\n\n");
return;
}
fclose(fp);
} void load()//载入数据
{
int i;
FILE *fp;
fp = fopen("book.bin", "rb"); //以只读方式打开二进制文件
if(fp != NULL)
{
fread(&RN, sizeof(int), , fp);
fread(books, sizeof(book), RN, fp);
printf("载入文件成功.\n");
}
else
{
printf("\n\n未找到数据文件book.bin,载入文件失败.\n\n");
printf("将新建数据文件book.bin .\n\n");
return;
}
fclose(fp);
} void delete_file()//删除历史文件
{
FILE *fp;
if(ask() == )
{
system("rm book.bin");
//linux系统下的删除文件命令
//system("del /q /f book.bin");
fp = fopen("book.bin", "r");
if(fp == NULL)
{
printf("删除数据文件成功.\n\n");
printf("但缓存中结构体数据依然存在.\n");
printf("是否清空这些缓存的数据?\n");
if(ask() == )
{
memset(books, , sizeof(books));//清空结构体数据
RN = ;//清空库存数量
printf("缓存数据已清空.\n\n");
}
else
{
printf("缓存数据未清空.\n\n");
}
}
else
printf("删除数据文件失败.\n\n");
}
else
printf("文件保留成功.\n\n");
printf("回车符返回主菜单.\n");
getchar();
getchar(); } int ask()//用于确认操作
{
char choice[];
printf("是否执行该操作? y/n\n");
scanf("%s", choice);
if(strcmp(choice, "y") == || strcmp(choice, "Y") == )
return ;
else
return ;
} int choice()//用于选择操作
{
char choice[];
printf("请输入:\n");
scanf("%s", choice);
if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else if(strcmp(choice, "") == )
return ;
else
printf("输入格式有误,请重试.\n");
} void display()
{
int i;
project();
for(i = ; i < RN; i++)
{
info(i);
}
printf("\n回车符返回主菜单\n");
// getchar();//用于吸收上一次输入到缓存区的数据
// fflush(stdin);//清空上一次输入缓存区 Linux系统下无效
// while((ch = getchar() != '\n' && ch != EOF));
// setbuf(stdin, NULL);
Clear_buffer//调用宏定义的函数清空上一次输入缓存区数据 与上两注释语句等效
getchar(); } int check_name(char name[])//检查输入书名是否与库存图书相同
{
int i, flag = ;
for(i = ; i < RN; i++)
{
if(strcmp(name, books[i].name) == )
flag++;
}
if(flag != )
{
printf("\n图书名称录入失败.\n");
printf("图书名称已存在,请重新输入.\n\n");
return ;
}
else
return ;
} int check_isn(char isn[])//检查图书ISN码
{
int i, flag = ;
for(i = ; i < RN; i++)
{
if(strcmp(isn, books[i].isn) == )
flag++;
}
if(flag != )
{
printf("\n图书ISN码录入失败.\n");
printf("此图书ISN码已存在,请重新输入.\n\n");
return ;
}
else
return ;
}
int check_data(char data[], int judge)//判断输入数据是否合法 judge用来判断是否为浮点型 1 为浮点型 0 为整型
{
int i, n, flag = ;
n = strlen(data);
for(i = ; i < n; i++)
{
if(judge == )
{
if((data[i] != '.') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != ''))
flag++;
}
else
{
if((data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != '') && (data[i] != ''))
flag++;
}
}
if(flag != )
{
printf("\n输入数据不合法,请检查后重试.\n");
return ;
}
else
return ;
} void addition()//增加数据
{
BN = ;
char price[], number[];
while()//循环输入 直到满足条件再退出
{
while()//检查图书库中是否存在相同名称图书
{
printf("请输入第 %d 本图书的名称:\n", BN+);
scanf("%s", books[RN].name);//RN为库存图书数量
if(check_name(books[RN].name) == )
break;
}
while()//检查图书库中是否存在相同ISN码图书
{
printf("ISN 码:\n");
scanf("%s", books[RN].isn);
if(check_isn(books[RN].isn) == )
break;
}
printf("作者:\n");
scanf("%s", books[RN].author);
while()//检查输入是否有效
{
printf("价格:\n");
scanf("%s", price);
if((check_data(price, )) == )
break;
}
books[RN].price = atof(price);//字符转浮点型
while()
{
printf("数量:\n");
scanf("%s", number);
if((check_data(number, )) == )
break;
}
books[RN].number = atoi(number);//字符转整型
RN++;
BN++;
printf("图书已添加成功.\n\n");
if(RN >= )
{
printf("已达库存上限 100000 本图书.\n");
printf("请清理后再录入.\n");
printf("回车符返回主菜单.\n");
Clear_buffer
getchar();
}
else
{
printf("是否继续添加图书?\n");
if(ask() != )
break;
}
}
printf("已成功添加了 %d 本图书.\n\n", BN);
} void delete()//删除数据
{
int i, mark = -, flag = ;//检查点 标记点
char name[];
mark = seek();
if(mark != -)
{
printf("是否删除此图书?\n");
if(ask() == )
{
for( i = ; i < RN; i++)
{
strcpy(books[mark].name, books[mark+].name);
strcpy(books[mark].isn, books[mark+].isn);
strcpy(books[mark].author, books[mark+].author);
books[mark].price = books[mark+].price;
books[mark].number = books[mark+].number;
}
RN--;//图书数量减少
printf("图书删除成功.\n\n");
printf("是否继续进行删除操作?\n");
if(ask() == )
delete();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
else
{
printf("已保留此图书.\n\n");
printf("是否继续进行删除操作?\n");
if(ask() == )
delete();
else
{
printf("回车符返回主菜单...\n");
getchar();
getchar();
}
}
}
else
{
printf("未找到此图书,请检查输入信息.\n\n");
printf("是否继续进行删除操作?\n");
if(ask() == )
delete();
else
{
printf("回车符退出操作,返回主菜单\n");
getchar();
getchar();
}
}
} int seek(int state)//查找数据
// state 为状态标志
// 1 为单纯使用本函数查找
// 2 为删除函数使用此函数查找
// 3 为修改函数使用此函数查找
{
int i, mark = -,flag = , option, flags[];
//flags[1000]用来统计同一作者图书的序号 option用于选择操作 flag用来判断是否有结果
char name[], author[], isn[], choices[];//choices[10]选择操作序号 与choice() 不一样序号大小范围大
//判断是否有其它函数进行调用 如有则返回对应值
for(i = ; i < ; i++)
flags[i] = -;//初始化其中的值全为-1 以免与图书的序号冲突
if(state == )
printf("\n||无其它函数调用此函数.\n\n");
else if(state == )
printf("\n||正在调用查找函数...\n\n");
else if(state == )
printf("\n||正在调用查找函数...\n\n");
printf("请选择查找信息的条件:\n");
printf("\t\t\t 1.名称 2.作者 3.ISN码\n");
option = choice();
switch(option)
{
case :
printf("按图书名称查找\n");
printf("请输入查找图书名称:\n");
scanf("%s", name);
for(i = ; i < RN; i++)
{
if(strcmp(name, books[i].name) == )
{
flag++;
mark = i;
}
}
if(flag != )
{
printf("已找到此信息匹配的图书\n");
printf("该图书信息如下:\n");
project();
info(mark);
printf("\n");
if(state != )
return mark;
else
{
printf("是否继续进行查找图书?\n");
if(ask() == )
seek();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
}
else
{
printf("未找到与此信息匹配的图书.\n\n");
printf("请检查输入信息.\n");
if(state != )
{
printf("是否继续进行查找来选择需要操作的图书?\n");
if(ask() == )
seek(state);
else
{
printf("回车符返回上一步.\n");
getchar();
getchar();
return -;
}
}
else
{
printf("是否继续进行查找操作?\n");
if(ask() == )
seek();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
}
break;
case ://考虑多个同名作者的情况
printf("按图书作者查找.\n");
printf("请输入查找图书作者:\n");
scanf("%s", author);
for(i = ; i < RN; i++)
{
if(strcmp(author, books[i].author) == )
{
flag++;
if(flag != )
{
flags[i] = i;
}
}
}
if(flag != )
{
printf("已找到此信息匹配的图书\n");
printf("该图书信息如下:\n");
project();
for(i = ; i < ; i++)
{
if(flags[i] != -)
info(flags[i]);
}
if(state != )
{
printf("请选择你要操作的图书序号:\n");
while()
{
scanf("%s", choices);
if(check_data(choices, ) == )
{
for(i = ; i < ; i++)
{
if(flags[i] == atoi(choices) - )
mark = flags[i];
}
if(mark != -)//mark 初始值为 -1 如改变则返回值
return mark;//实际的存储地址从0地址开始 因此-1
else
{
printf("没有那个选项.\n");
printf("是否重试?\n");
if(ask() == )
return -;
printf("请重试输入:\n");
}
}
else
{
printf("没有那个选项.\n");
printf("是否重试?\n");
if(ask() == )
return -;
printf("请重新输入:\n");
}
}
}
else
{
printf("是否继续进行查找图书?\n");
if(ask() == )
seek();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
}
else
{
printf("未找到与此信息匹配的图书.\n\n");
printf("请检查输入信息.\n");
if(state != )
{
printf("是否继续进行查找来选择需要操作的图书?\n");
if(ask() == )
seek(state);
else
{
printf("回车符返回上一步.\n");
getchar();
getchar();
return -;
}
}
else
{
printf("是否继续进行查找操作?\n");
if(ask() == )
seek();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
}
break;
case :
printf("按图书ISN码查找.\n");
printf("请输入查找图书ISN码:\n");
scanf("%s", isn);
for(i = ; i < RN; i++)
{
if(strcmp(isn, books[i].isn) == )
{
flag++;
mark = i;
}
}
if(flag != )
{
printf("已找到此信息匹配的图书\n");
printf("该图书信息如下:\n");
project();
info(mark);
printf("\n");
if(state != )
return mark;
else
{
printf("是否继续进行查找图书?\n");
if(ask() == )
seek();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
}
else
{
printf("未找到与此信息匹配的图书.\n\n");
printf("请检查输入信息.\n");
if(state != )
{
printf("是否继续进行查找来选择需要操作的图书?\n");
if(ask() == )
seek(state);
else
{
printf("回车符返回上一步.\n");
getchar();
getchar();
return -;
}
}
else
{
printf("是否继续进行查找操作?\n");
if(ask() == )
seek();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
}
break;
default:
printf("输入有误,请重新输入.\n");
printf("请检查后重新输入.\n");
if(state != )
{
printf("是否继续进行查找来选择需要操作的图书?\n");
if(ask() == )
seek(state);
else
{
printf("回车符返回上一步.\n");
getchar();
getchar();
return -;
}
}
else
{
printf("是否继续进行查找操作?\n");
if(ask() == )
seek();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
break;
}
} void modify()//修改数据
{
int n, option;
char name[], isn[], author[], price[], number[];
n = seek();
if( n != -)
{
printf("请选择要修改图书的项目:\n");
printf("\t\t\t1.名称 2.ISN 3.作者 4.价格 5.数量\n");
option = choice();
switch(option)
{
case :
printf("修改此图书名称.\n");
while()
{
printf("请输入修改后的名称:\n");
scanf("%s", name);
if(check_name(name) == )
break;
}
strcpy(books[n].name, name);
if(strcmp(books[n].name, name) == )
printf("图书名称修改成功.\n\n");
else
printf("图书名称修改失败.\n\n");
printf("是否继续修改操作?\n");
if(ask() == )
modify();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
break;
case :
printf("修改此图书ISN码.\n");
while()
{
printf("请输入修改后的ISN码:\n");
scanf("%s", isn);
if(check_isn(isn) == )
break;
}
strcpy(books[n].isn, isn);
if(strcmp(books[n].isn, isn) == )
printf("图书ISN码修改成功.\n\n");
else
printf("图书ISN码修改失败.\n\n");
printf("是否继续进行查找操作? \n");
printf("是否继续修改操作?\n");
if(ask() == )
modify();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
break;
case :
printf("修改此图书作者.\n");
printf("请输入修改后的作者:\n");
scanf("%s", author);
strcpy(books[n].author, author);
if(strcmp(books[n].author, author) == )
printf("图书作者修改成功.\n\n");
else
printf("图书作者修改失败.\n\n");
printf("是否继续进行修改操作?\n");
if(ask() == )
modify();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
break;
case :
printf("修改此图书价格,\n");
while()//检查修改输入数据是否有效
{
printf("请输入修改后的价格:\n");
scanf("%s", price);
if(check_data(price, ) == )
{
books[n].price = atof(price);
break;
}
}
//不判断是否修改成功 因为浮点型不好比较 精度高
printf("图书价格修改成功.\n\n");
printf("是否继续进行修改操作?\n");
if(ask() == )
modify();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
break;
case :
printf("修改此图书数量.\n");
while()
{
printf("请输入修改后的数量:\n");
scanf("%s", number);
if(check_data(number, ) == )
{
books[n].number = atoi(number);
break;
}
}
if(books[n].number == atoi(number))
printf("图书价格修改成功.\n\n");
else
printf("图书价格修改失败.\n\n");
printf("是否继续进行修改操作?\n");
if(ask() == )
modify();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
break;
default:
printf("输入错误,没有那个选项.\n");
printf("请重新输入.\n");
printf("是否继续进行修改操作?\n");
if(ask() == )
modify();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
break;
}
}
else
{
printf("未找到与此信息匹配的图书.\n\n");
printf("是否继续进行修改操作?\n");
if(ask() == )
modify();
else
{
printf("回车符返回主菜单.\n");
getchar();
getchar();
}
}
} void sort_number()
{
int i, j;
book temp;//中间临时结构体
float price;
for(i = ; i < RN-; i++)//冒泡排序
{
for(j = ; j < RN-i-; j++)
{
if(books[j].number > books[j+].number)
{
temp = books[j];
books[j] = books[j+];
books[j+] = temp;
}
}
}
project();
for(i = ; i < RN; i++)
{
info(i);
}
printf("所做的更改仅存在于缓存区内和打印在屏幕上.\n");
printf("那么,是否将这些改动写入文件?\n");
if(ask() == )
save();
else
{
printf("文件内容未改动.\n\n");
}
printf("回车符返回主菜单.\n");
Clear_buffer
getchar();
} void sort_price()
{
int i, j;
book temp;
float price;
for(i = ; i < RN-; i++)
{
for(j = ; j < RN-i-; j++)
{
if(books[j].price > books[j+].price)
{
temp = books[j];
books[j] = books[j+];
books[j+] = temp;
}
}
}
project();
for(i = ; i < RN; i++)
{
info(i);
}
printf("所做的更改仅存在于缓存区内和打印在屏幕上.\n");
printf("并不会写入文件中.");
printf("那么,是否将这些改动写入文件?\n");
if(ask() == )
save();
else
{
printf("文件内容未改动.\n\n");
}
printf("回车符返回主菜单.\n");
Clear_buffer
getchar();
} void quit()
{
sleep();//sleep(*)以秒为单位
//Sleep(2000);Sleep(*)以毫秒为单位
//system("clss");
system("clear");
} void menu()//菜单列表
{
int option;
printf("\t\t\t\t --图书管理系统--\n");
printf("\t\t\t\t**************************\n");
printf("\t\t\t\t* 1.查看图书信息 *\n");
printf("\t\t\t\t* 2.增加图书信息 *\n");
printf("\t\t\t\t* 3.删除图书信息 *\n");
printf("\t\t\t\t* 4.查找图书信息 *\n");
printf("\t\t\t\t* 5.修改图书信息 *\n");
printf("\t\t\t\t* 6.删除图书数据 *\n");
printf("\t\t\t\t* 7.图书数量排序 *\n");
printf("\t\t\t\t* 8.图书价格排序 *\n");
printf("\t\t\t\t* 9.退出图书系统 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* --@phl *\n");
printf("\t\t\t\t**************************\n");
option = choice();//由选择函数赋值
switch(option)
{
case :
system("clear");
//system("cls");
border_x();
border_y();
printf("\t\t图书信息展示");
border_y();
border_x();
display();
break;
case :
border_x();
border_y();
printf("\t\t增加图书操作");
border_y();
border_x();
addition();
save();
break;
case :
border_x();
border_y();
printf("\t\t图书删除操作");
border_y();
border_x();
delete();
save();
break;
case :
border_x();
border_y();
printf("\t\t图书查找操作");
border_y();
border_x();
seek();
break;
case :
border_x();
border_y();
printf("\t\t图书修改操作");
border_y();
border_x();
modify();
save();
break;
case :
border_x();
border_y();
printf("\t\t数据删除操作");
border_y();
border_x();
delete_file();
break;
case :
system("clear");
//system("cls");
border_x();
border_y();
printf("\t\t图书数量排序");
border_y();
border_x();
sort_number();
break;
case :
system("clear");
//system("cls");
border_x();
border_y();
printf("\t\t图书价格排序");
border_y();
border_x();
sort_price();
break;
case :
system("clear");
//system("cls");
border_x();
border_y();
printf("\t\t系统退出操作");
border_y();
border_x();
quit();
exit();
break;
default:
system("clear");
//system("cls");
printf("没有那个选项.\n");
printf("请检查后重新输入.\n\n");
menu();
break;
}
} void main()
{
load();//载入历史文件
while()
{
menu();
}
}
C语言: 简易图书管理系统的更多相关文章
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(3) - 使用Conductor切换页面
前两章中, 我们已经实现了这个图书管理系统的登录窗口, 并实施了完善的单元测试. 该是时候回过头来关注我们的主窗口了. 一个功能丰富的系统一般会有多个页面, 我们图书管理系统虽然是"简易&q ...
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(4) - 图书列表界面
在前三章中我们完成了登录窗口, 并掌握了使用Conductor来切换窗口, 但这些其实都是在为我们的系统打基础. 而本章中我们就要开始开发系统的核心功能, 即图书管理功能了. 通过本章, 我们会接触到 ...
- 简易图书管理系统(主要是jsp的练习)
1:首先设计用户表和图书表,设计的字段和类型如下图所示 1.1:用户表user 1.2:图书表book 2:第二写实体类user.java和book.java package com.bie.po; ...
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(1)
.NET Core 3.0已经发布了,除了一大堆令人激动的功能以外,也增加了对WPF的正式支持, 那么WPF在.NET Core 3.0下的开发体验如何呢? 本文利用了Stylet框架开发.NET C ...
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(2) - 单元测试
上一章中我们完成了一个简单的登录功能, 这一章主要演示如何对Stylet工程中的ViewModel进行单元测试. 回忆一下我们的登录逻辑,主要有以下4点: 当"用户名"或" ...
- 基于jsp+servlet图书管理系统之后台万能模板
前奏: 刚开始接触博客园写博客,就是写写平时学的基础知识,慢慢发现大神写的博客思路很清晰,知识很丰富,非常又价值,反思自己写的,顿时感觉非常low,有相当长一段时间没有分享自己的知识.于是静下心来钻研 ...
- 基于jsp+servlet图书管理系统之后台用户信息查询操作
上一篇的博客写的是插入操作,且附有源码和数据库,这篇博客写的是查询操作,附有从头至尾写的代码(详细的注释)和数据库! 此次查询操作的源码和数据库:http://download.csdn.net/de ...
- 基于jsp+servlet图书管理系统之后台用户信息修改操作
上一篇的博客写的是查询操作,且附有源码和数据库,这篇博客写的是修改操作,附有从头至尾写的代码(详细的注释)和数据库! 此次修改操作的源码和数据库:http://download.csdn.net/de ...
- 基于jsp+servlet图书管理系统之后台用户信息删除操作
上一篇的博客写的是修改操作,且附有源码和数据库,这篇博客写的是删除操作,附有从头至尾写的代码(详细的注释)和数据库! 此次删除操作的源码和数据库:http://download.csdn.net/de ...
随机推荐
- 魅族资深DBA:利用MHA构建MySQL高可用平台
龙启东 魅族资深DBA 负责MySQL.Redis.MongoDB以及自动化平台建设 .擅长MySQL高可用方案.SQL性能优化.故障诊断等. 本次分享主要包括以下几方面: 如何利用MHA 改造MHA ...
- C#基础加强(9)之对象序列化(二进制)
介绍 对象序列化是将对象转换为二进制数据(字节流),反序列化是将二进制数据还原成对象.对象的非持久态的,不仅在程序重启.操作系统重启会造成对象的丢失,就是退出函数范围等都可能造成对象的消失,而序列化与 ...
- Xpath语法详解
1.简介 XPath是一门在XML和HTML文档中查找信息的语言,可以用来在XML和HTML文档中对元素和属性进行遍历 XPath的安装 Chrome插件XPath Helper 点Chrome浏览器 ...
- Ch07 包和引入 - 练习
1. 编写示例程序,展示为什么 package com.horstmann.impatient 不同于 package com package horstmann package impatien ...
- 安装mongodb服务
摘要:https://www.cnblogs.com/z-x-y/p/9305635.html 欢迎转载,转载请标明出处:https://www.cnblogs.com/z-x-y/p/9305635 ...
- C++模板的要点
1.函数模板与普通函数的区别: 普通函数可以进行自动类型转化,而函数模板不可以. 举个例子 //函数模板 template<class T> void show(T a,T b){ cou ...
- unity组件路径自动生成
unity 有时候找路径太麻烦 写了一个自动生成脚本的工具 using System.Collections.Generic; using System.IO; using System.Text; ...
- Wireshark常用过滤命令
WireShark在我们网络编程中有非常重要的作用,可以帮我们抓取我们程序发送的数据包,大家常常说他是抓包工具,其实它是一款非常强大的网络数据包分析工具. 在WireShark的学习上,不想花费太多的 ...
- WCF 重载
[ServiceContract] public interface IUser { [OperationContract(Name="ByUseId")] User GetUse ...
- Python记录wsgi
类实现wsgi app from wsgiref.util import setup_testing_defaults from wsgiref.simple_server import make_s ...