【MySQL】数据库-图书管理系统(CC++实现)

news2025/3/1 13:26:53

一.预期功能

该图书管理系统设计提供基本的设计模版,涉及数据库的增删查改等操作,包含登录功能,图书管理功能,图书借阅功能,用户管理功能等基础功能,详细功能查看以下菜单表,共包含三个菜单,登录菜单,管理员菜单和用户菜单。

void Menu()
{
	printf("***************************************
");
	printf("*      欢迎进入线上图书管理系统!     *
");
	printf("*                                     *
");
	printf("*            1.管理员登录             *
");
	printf("*            2.读者登录               *
");
	printf("*            3.读者注册               *
");
	printf("*            0.退出本系统             *
");
	printf("***************************************
");
}
void manager_Menu()
{
	printf("***************************************
");
	printf("*            欢迎你,管理员            
");
	printf("*                                     
");
	printf("*            1.添加书籍              
");
	printf("*            2.显示书籍              
");
	printf("*            3.查找书籍               
");
	printf("*            4.修改书籍               
");
	printf("*            5.显示用户数据            
");
	printf("*            6.返回主菜单              
");
	printf("*            7.添加新管理员              
");
	printf("*            0.退出本系统             
");
	printf("***************************************
");
}
void reader_Menu(user* head)
{
	printf("***************************************
");
	printf("*          欢迎你,读者           
");
	printf("*                                     
");
	printf("*          1.借阅书籍                  
");
	printf("*          2.归还书籍                  
");
	printf("*          3.修改密码                  
");
	printf("*          4.返回主菜单                
");
	printf("*          0.退出本系统                
");
	printf("*                                     
");
	printf("***************************************
");
}

二.建表

1.管理员表(manager)

列名

数据类型

约束

说明

M_ID

INT

PRIMARY KEY

管理员ID编号

M_Account

VARCHAR(30)

NOT NULL

管理员账号

M-Password

VARCHAR(30)

NOT NULL

密码

2.图书信息表(book)

列名

数据类型

约束

说明

B_ID

INT

PRIMARY KEY

图书ID编号

B_Name

VARCHAR(30)

NOT NULL

图书名称

Author

VARCHAR(30)

NOT NULL

作者

Publish

VARCHAR(30)

NOT NULL

出版社名称

Price

DECIMAL(10,2)

NOT NULL

价格

Quantity

INT

DEFAULT 0

库存量

3.用户表(user)

列名

数据类型

约束

说明

U_ID

INT

PRIMARY KEY

用户ID编号

U_Account

VARCHAR(30)

NOT NULL

用户账号

U_Password

VARCHAR(30)

NOT NULL

密码

4.借书表(borrow_book)

列名

数据类型

约束

说明

U_ID

INT

FOREIGN KEY

用户ID编号

B_ID

INT

FOREIGN KEY

图书ID编号

Borrow_time

VARCHAR(30)

NOT NULL

借阅时间

Return_time

VARCHAR(30)

NOT NULL

归还时间

State

VARCHAR(30)

NOT NULL

状态

备注1:登录功能使用管理员账号/用户账号+密码进行登录,在这里省略了管理员/用户昵称。

备注2:价格DECIMAL对应VS中的float(浮点型)进行转化。

备注3:时间可以使用Date类型,但为了方便在VS中添加到数据库使用varchar类型,在VS上将当前时间转化为字符串进行添加。

备注4:借书表中U_ID和B_ID共同构成主码。

附上MySQL建表,数据插入代码:

CREATE TABLE manager(
M_ID INT PRIMARY KEY,
M_Account VARCHAR(30) NOT NULL,
M_Password VARCHAR(30) NOT NULL
);

CREATE TABLE book(
B_ID INT PRIMARY KEY,
B_NAME VARCHAR(30) NOT NULL,
Author VARCHAR(30) NOT NULL,
Publish VARCHAR(30) NOT NULL,
Price DECIMAL(10,2) NOT NULL,
Quantity INT DEFAULT 0
);

CREATE TABLE user(
U_ID INT PRIMARY KEY,
U_Account VARCHAR(30) NOT NULL,
U_Password VARCHAR(30) NOT NULL
);

CREATE TABLE borrow_book(
U_ID INT NOT NULL,	
B_ID INT NOT NULL,
Borrow_time VARCHAR(30) NOT NULL,
Return_time VARCHAR(30),
State VARCHAR(30),
PRIMARY KEY (U_ID,B_ID),
FOREIGN KEY(U_ID) REFERENCES user(U_ID) ON DELETE CASCADE,
FOREIGN KEY(B_ID) REFERENCES book(B_ID) ON DELETE CASCADE
);

-- 管理员表数据
INSERT INTO manager (M_ID, M_Account, M_Password) VALUES
(3, 'alice_admin', 'alice123'),
(4, 'bob_admin', 'bob123'),
(5, 'charlie_admin', 'charlie123');

-- 书籍表数据
INSERT INTO book (B_ID, B_NAME, Author, Publish, Price, Quantity) VALUES
(101, '百年孤独', '加布里埃尔·加西亚·马尔克斯', '南海出版公司', 59.90, 20),
(102, '追风筝的人', '卡勒德·胡赛尼', '上海人民出版社', 39.50, 15),
(103, '解忧杂货店', '东野圭吾', '南海出版公司', 39.00, 30),
(104, '活着', '余华', '北京十月文艺出版社', 35.00, 25),
(105, '哈利·波特与魔法石', 'J.K.罗琳', '人民文学出版社', 69.00, 50);

-- 用户表数据
INSERT INTO user (U_ID, U_Account, U_Password) VALUES
(201, 'diana_user', 'diana123'),
(202, 'eric_user', 'eric123'),
(203, 'fiona_user', 'fiona123'),
(204, 'george_user', 'george123'),
(205, 'hannah_user', 'hannah123');

-- 借阅记录表数据
INSERT INTO borrow_book (U_ID, B_ID, Borrow_time, Return_time, State) VALUES
(201, 101, '2024-06-01', '2024-06-15', 'RETURNED'),
(202, 102, '2024-06-02', NULL, 'BORROWED'),
(203, 103, '2024-06-03', '2024-06-10', 'RETURNED'),
(204, 104, '2024-06-04', NULL, 'BORROWED'),
(205, 105, '2024-06-05', '2024-06-20', 'RETURNED'),
(201, 105, '2024-06-21', NULL, 'BORROWED');

三.环境配置

声明:本文使用Visual studio2022 编写,其他编译器可自行考量,下面进行环境配置。

首先,找到项目的属性页面,找到C/C++,在常规的附加包含目录中选中安装的MySQL文件中的Include文件

然后在连接器的常规中,找到附加库目录,选中mysql文件中的lib文件

在链接器的输入中,选择附加依赖项,手动输入libmysql.lib

最后一步,将MySQL文件lib文件中的libmysql.dll复制到项目的x64目录下。

这样环境就配置好了。

四.数据库连接

这是链接数据库和编译器的起点,系统整体的功能都在这个实现内部,注意设置字符编码,否则可能会出现乱码。

//初始化
MYSQL* con = mysql_init(NULL);

//设置字符编码,以防出现乱码
mysql_options(con, MYSQL_SET_CHARSET_NAME, "GBK");

//开始连接
if (!mysql_real_connect(con, host, use, password, database_name, port, NULL, 0))
{
	fprintf(stderr, "connect fail", mysql_error(con));
	return -1;
}

//关闭连接
mysql_close(con);

五.添加、删除信息

在编译器中定义表格数据对应的结构体,在编译器中输入的数据存入结构体链表中,在通过sprintf将对应的MySQL插入/删除语句输出执行。本系统在VS上使用结构体链表储存对应表格的所有数据,因此设置三个链表的头指针:book_head,user_head,manager_head,初始化为NULL

//结构体定义
typedef struct manager_table
{
	int M_ID;
	char M_Account[30];
	char M_Password[30];
	struct manager_table* next;
}manager;

typedef struct book_table
{
	int B_ID;
	char B_NAME[30];
	char Author[30];
	char Publish[30];
	float Price;
	int Quantity;
	struct book_table* next;
}book;

typedef struct user_table
{
	int U_ID;
	char U_Account[30];
	char U_Password[30];
	struct user_table* next;
}user;


    //链表头节点指针
	book* book_head = NULL;
	user* user_head = NULL;
	manager* manager_head = NULL;

添加新书籍首先找到链表的尾部,创建新节点,将书籍信息输入,随后将mysql语句存入字符数组sql中,使用mysql_query即可。当然在编号输入中可以添加重复检查等功能,实现就是链表的遍历,在此不进行实现该功能。书籍添加实现,其余管理员添加,用户添加也是同理。

book* Add_new_book(book* head, MYSQL* mysql)
{
	book* newbook = (book*)malloc(sizeof(book));
	if (newbook == NULL)
	{
		perror("malloc fail");
		exit(1);
	}

	if (head == NULL)
	{
		head = newbook;
	}
	else
	{
		//找到尾节点
		book* pcur = head;
		while (pcur->next)
		{
			pcur = pcur->next;
		}
		pcur->next = newbook;
	}

	printf("请输入书籍编号:");
	scanf("%d", &(newbook->B_ID));

	//检测编号重复(未实现)

	printf("请输入名称:");
	scanf("%s", newbook->B_NAME);
	printf("请输入作者:");
	scanf("%s", newbook->Author);
	printf("请输入出版社:");
	scanf("%s", newbook->Publish);
	printf("请输入价格:");
	scanf("%f", &(newbook->Price));
	printf("请输入库存量:");
	scanf("%d", &(newbook->Quantity));

	//将新增书籍信息存入数据库
	char sql[256];
	sprintf(sql, "insert into book values('%d','%s','%s','%s','%f','%d')",
		newbook->B_ID, newbook->B_NAME, newbook->Author, newbook->Publish, newbook->Price, newbook->Quantity);
	mysql_query(mysql, sql);

	newbook->next = NULL;
	printf("添加成功!
");
	return head;
}

删除书籍需要进行以下两步:找到对应编号的节点,然后释放该节点。防止删除错误,加入了删除时显示书籍信息并且进行二次确认功能。

//删除书籍信息
book* Delete_Book(book* head, MYSQL* mysql)
{
	book* p = head;
	book* pcur = NULL;
	int id, option;
	char sql[256];
	printf("请输入删除书籍的编号:");
	scanf("%d", &id);
	while (p)
	{
		if (id == p->B_ID)
		{
			break;
		}
		pcur = p;
		p = p->next;
	}
	if (p == NULL)
	{
		printf("未找到此ID编号的书籍
");
		return 0;
	}
	else
	{
		printf("===================================================================================
");
		printf("|书名                    |作者            |出版社          |价格  |库存  |编号    |
");
		printf("-----------------------------------------------------------------------------------
");
		printf("|%-24s|%-16s|%-16s|%-6.2f|%-6d|%-8d|
", p->B_NAME, p->Author, p->Publish, p->Price, p->Quantity, p->B_ID);
		printf("===================================================================================
");

		printf("================
");
		printf("|是否确定删除?|
");
		printf("|0.取消  1.确定|
");
		printf("================
");

		scanf("%d", &option);
		switch (option)
		{
		case 1:
			sprintf(sql, "delete from book where B_ID = %d;", id);
			mysql_query(mysql, sql);
			if (p == head)
			{
				head = head->next;
				free(p);
			}
			else
			{
				pcur->next = p->next;
				free(p);
			}
			printf("已成功删除
");
			option = 0;
			break;
		case 0:
			printf("取消删除
");
			break;
		default:
			printf("输入错误
");
			break;
		}
	}
	return head;
}

六.加载数据库信息

在加载数据库的信息前需要定义res 和 row来查询结果集和记录结构体,随后将获得的结果插入进链表,将数据库的内容拷贝到编译器的链表中。

MYSQL_RES* res = NULL;//查询结果集
MYSQL_ROW row = NULL;//记录结构体

//从数据库中加载书籍信息
book* load_Book(book* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql)
{
	book* p = NULL;
	book* pcur = head;

	//查询数据
	mysql_query(mysql, "select * from book;");

	//获取结果集
	res = mysql_store_result(mysql);

	//将值赋为链表
	while (row = mysql_fetch_row(res))
	{
		p = NULL, pcur = head;
		p = (book*)malloc(sizeof(book));
		if (p == NULL)
		{
			perror("malloc fail");
			exit(1);
		}

		if (head == NULL)
		{
			head = p;
		}
		else
		{
			while (pcur->next != NULL)
			{
				pcur = pcur->next;
			}
			pcur->next = p;
		}

		p->B_ID = atoi(row[0]);
		strcpy(p->B_NAME, row[1]);
		strcpy(p->Author, row[2]);
		strcpy(p->Publish, row[3]);
		p->Price = atoi(row[4]);
		p->Quantity = atoi(row[5]);
		p->next = NULL;
	}

	//释放结果集
	mysql_free_result(res);
	return head;
}

七.查找与登录

使用者输入账号存入account数组,遍历链表使用strcmp进行比较,匹配成功后再输入密码进行对比,密码有可能输入错误,设置循环再次尝试。

manager* manager_Login(manager* head)
{
	manager* p = head;
	char account[30], password[30];
	printf("请输入账号:");
	scanf("%s", account);
	while (p != NULL)
	{
		if (!strcmp(account, p->M_Account))
		{
			break;
		}
		p = p->next;
	}
	if (p == NULL)
	{
		printf("没有查找到该账号!
");
		return NULL;
	}
	else
	{
		while (1)
		{
			printf("请输入密码:");
			scanf("%s", password);
			if (strcmp(password, p->M_Password) == 0)
			{
				printf("成功登录!
");
				break;
			}
			else {
				printf("密码错误!请重新输入!
");
			}
		}
	}

	return p;
}

八.借阅与归还

借阅归还中与前面不同的就在于时间,在VS中得到当前日期的字符数组,可以这样实现:

#include<time.h>

time_t rawtime;
struct tm* timeinfo;
char date_str[11]; // 足够存储 "YYYY-MM-DD" 格式的日期字符串

// 获取当前时间的时间戳
time(&rawtime);

// 将时间戳转换为本地时间
timeinfo = localtime(&rawtime);

// 使用sprintf将年、月、日格式化为字符串
// 注意:tm_year是从1900年开始的,所以需要+1900
// tm_mon是从0开始的,所以需要+1
sprintf(date_str, "%d-%02d-%02d",
				timeinfo->tm_year + 1900,
				timeinfo->tm_mon + 1,
				timeinfo->tm_mday);

因此在借阅时,填入借阅时间,并将状态改为“BORROWED”,在归还时填入归还时间,并将状态改为“RETURNED”即可。

//借阅图书
int borrow_book(int id, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql, book* head)
{
	Show_remaining_book(res, row, mysql);
	char sql[256];
	int b_id;
	book* p = head;
	printf("请输入要借阅的书籍编号:");
	scanf("%d", &b_id);

	while (head != NULL)
	{
		if (b_id == p->B_ID)
		{
			sprintf_s(sql, sizeof(sql), "select * from book where B_ID = %d;", b_id);
			mysql_query(mysql, sql);
			res = mysql_store_result(mysql);
			row = mysql_fetch_row(res);
			if (atoi(row[5]) <= 0)
			{
				printf("库存量不足!
");
				return 0;
			}
			else
			{
				time_t rawtime;
				struct tm* timeinfo;
				char date_str[11]; // 足够存储 "YYYY-MM-DD" 格式的日期字符串

				// 获取当前时间的时间戳
				time(&rawtime);

				// 将时间戳转换为本地时间
				timeinfo = localtime(&rawtime);

				// 使用sprintf将年、月、日格式化为字符串
				// 注意:tm_year是从1900年开始的,所以需要+1900
				// tm_mon是从0开始的,所以需要+1
				sprintf(date_str, "%d-%02d-%02d",
					timeinfo->tm_year + 1900,
					timeinfo->tm_mon + 1,
					timeinfo->tm_mday);

				sprintf(sql, "insert into borrow_book values (%d,%d,'%s','%s','%s');", id, b_id, date_str, "NULL", "BORROWED");
				mysql_query(mysql, sql);
				sprintf(sql, "update book set Quantity = Quantity - 1 where B_ID = %d;", b_id);
				mysql_query(mysql, sql);
				printf("借阅成功!
");
				return 0;
			}
		}
		p = p->next;
	}
	if (p == NULL) {
		printf("图书编号不存在
");
	}

	return 0;
}
//归还图书
int return_book(int id, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql, book* head)
{
	int b_id;
	book* p = head;
	char sql[256];
	printf("请输入要归还的书籍编号:");
	scanf("%d", &b_id);
	while (p != NULL)
	{
		if (b_id == p->B_ID)
		{
			time_t rawtime;
			struct tm* timeinfo;
			char date_str[11];
			time(&rawtime);
			timeinfo = localtime(&rawtime);
			sprintf(date_str, "%d-%02d-%02d",
				timeinfo->tm_year + 1900,
				timeinfo->tm_mon + 1,
				timeinfo->tm_mday);
			sprintf(sql, "update book set Quantity = Quantity + 1 where B_ID = %d;", p->B_ID);
			mysql_query(mysql, sql);
			sprintf(sql, "update borrow_book set Return_time = '%s', State = '%s' where U_ID = %d AND B_ID = %d;"
				, date_str, "RETURNED", id, p->B_ID);
			mysql_query(mysql, sql);
			printf("归还成功!
");
			break;
		}
		p = p->next;
	}
	if (p == NULL) 
	{
		printf("不存在该借出的图书!
");
	}

	return 0;
}

九.完整代码

备注:如果是C++要进行封装,可以建立对象book、manager、user等类,放入对应的结构体和函数方法即可实现,以下代码是按照C语言编写。

头文件:Library.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<mysql.h>
#include<time.h>


//结构体定义
typedef struct manager_table
{
	int M_ID;
	char M_Account[30];
	char M_Password[30];
	struct manager_table* next;
}manager;

typedef struct book_table
{
	int B_ID;
	char B_NAME[30];
	char Author[30];
	char Publish[30];
	float Price;
	int Quantity;
	struct book_table* next;
}book;

typedef struct user_table
{
	int U_ID;
	char U_Account[30];
	char U_Password[30];
	struct user_table* next;
}user;

//函数定义

//展示菜单
void Menu();
void manager_Menu();
void reader_Menu(user* head);
void show_Menu_user(user* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql);

//从数据库中加载书籍信息
book* load_Book(book* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql);

//添加新管理员
manager* Add_new_manager(manager* head, MYSQL* mysql);
//添加新借书记录
//borrow_book* Add_new_borrow(borrow_book* head, MYSQL* mysql);

//从数据库中加载书籍信息
book* load_Book(book* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql);
//从数据库中加载借阅信息


//添加新书籍
book* Add_new_book(book* head, MYSQL* mysql);
//展示书籍信息
void Show_All_book(book* head);
//查找书籍信息
void Search_book(book* head);
//删除书籍信息
book* Delete_Book(book* head, MYSQL* mysql);
//修改书籍信息
book* Change_book(book* head, MYSQL* mysql);


//添加新用户
user* Add_new_user(user* head, MYSQL* mysql);
//展示所有的用户信息
void Show_All_user(user* head);
//从数据库中加载用户信息
user* load_User(user* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql);
//从数据库中加载管理员信息
user* load_Manager(user* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql);
//修改用户密码
int Change_User_password(user* head, MYSQL* mysql);
//用户登陆
user* user_Login(user* head);
//管理员登录
manager* manager_Login(manager* head);

//显示有库存的书籍
void Show_remaining_book(MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql);
//借阅图书
int borrow_book(int id, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql, book* head);
//归还图书
int return_book(int id, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql, book* head);

源文件:Library.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Library.h"

//初始菜单
void Menu()
{
	printf("***************************************
");
	printf("*      欢迎进入线上图书管理系统!     *
");
	printf("*                                     *
");
	printf("*            1.管理员登录             *
");
	printf("*            2.读者登录               *
");
	printf("*            3.读者注册               *
");
	printf("*            0.退出本系统             *
");
	printf("***************************************
");
}
void manager_Menu()
{
	printf("***************************************
");
	printf("*            欢迎你,管理员            
");
	printf("*                                     
");
	printf("*            1.添加书籍              
");
	printf("*            2.显示书籍              
");
	printf("*            3.查找书籍               
");
	printf("*            4.修改书籍               
");
	printf("*            5.删除书籍               
");
	printf("*            6.显示用户数据            
");
	printf("*            7.返回主菜单              
");
	printf("*            8.添加新管理员              
");
	printf("*            0.退出本系统             
");
	printf("***************************************
");
}
void reader_Menu(user* head)
{
	printf("***************************************
");
	printf("*          欢迎你,读者           
");
	printf("*                                     
");
	printf("*          1.借阅书籍                  
");
	printf("*          2.归还书籍                  
");
	printf("*          3.修改密码                  
");
	printf("*          4.返回主菜单                
");
	printf("*          0.退出本系统                
");
	printf("*                                     
");
	printf("***************************************
");
}


//从数据库中加载书籍信息
book* load_Book(book* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql)
{
	book* p = NULL;
	book* pcur = head;

	//查询数据
	mysql_query(mysql, "select * from book;");

	//获取结果集
	res = mysql_store_result(mysql);

	//将值赋为链表
	while (row = mysql_fetch_row(res))
	{
		p = NULL, pcur = head;
		p = (book*)malloc(sizeof(book));
		if (p == NULL)
		{
			perror("malloc fail");
			exit(1);
		}

		if (head == NULL)
		{
			head = p;
		}
		else
		{
			while (pcur->next != NULL)
			{
				pcur = pcur->next;
			}
			pcur->next = p;
		}

		p->B_ID = atoi(row[0]);
		strcpy(p->B_NAME, row[1]);
		strcpy(p->Author, row[2]);
		strcpy(p->Publish, row[3]);
		p->Price = atoi(row[4]);
		p->Quantity = atoi(row[5]);
		p->next = NULL;
	}

	//释放结果集
	mysql_free_result(res);
	return head;
}

//添加新书籍
book* Add_new_book(book* head, MYSQL* mysql)
{
	book* newbook = (book*)malloc(sizeof(book));
	if (newbook == NULL)
	{
		perror("malloc fail");
		exit(1);
	}

	if (head == NULL)
	{
		head = newbook;
	}
	else
	{
		//找到尾节点
		book* pcur = head;
		while (pcur->next)
		{
			pcur = pcur->next;
		}
		pcur->next = newbook;
	}

	printf("请输入书籍编号:");
	scanf("%d", &(newbook->B_ID));

	//检测编号重复

	printf("请输入名称:");
	scanf("%s", newbook->B_NAME);
	printf("请输入作者:");
	scanf("%s", newbook->Author);
	printf("请输入出版社:");
	scanf("%s", newbook->Publish);
	printf("请输入价格:");
	scanf("%f", &(newbook->Price));
	printf("请输入库存量:");
	scanf("%d", &(newbook->Quantity));

	//将新增书籍信息存入数据库
	char sql[256];
	sprintf(sql, "insert into book values('%d','%s','%s','%s','%f','%d')",
		newbook->B_ID, newbook->B_NAME, newbook->Author, newbook->Publish, newbook->Price, newbook->Quantity);
	mysql_query(mysql, sql);

	newbook->next = NULL;
	printf("添加成功!
");
	return head;
}
//添加新用户
user* Add_new_user(user* head, MYSQL* mysql)
{
	user* newuser = (user*)malloc(sizeof(user));
	user* pcur = head;
	if (newuser == NULL)
	{
		perror("malloc fail");
		exit(1);
	}

	if (head == NULL)
	{
		head = newuser;
	}
	else
	{
		//找到尾节点
		book* pcur = head;
		while (pcur->next)
		{
			pcur = pcur->next;
		}
		pcur->next = newuser;
	}

	printf("请输入用户编号:");
	scanf("%d", &(newuser->U_ID));
	printf("请输入用户账号:");
	scanf("%s", newuser->U_Account);
	printf("请输入用户密码:");
	scanf("%s", newuser->U_Password);

	char sql[256];
	sprintf(sql, "insert into user values('%d','%s','%s')",
		newuser->U_ID, newuser->U_Account, newuser->U_Password);
	mysql_query(mysql, sql);

	newuser->next = NULL;
	printf("添加成功!
");
	return head;
}
//添加新管理员
manager* Add_new_manager(manager* head, MYSQL* mysql)
{
	manager* newmanager = (manager*)malloc(sizeof(manager));
	user* pcur = head;
	if (newmanager == NULL)
	{
		perror("malloc fail");
		exit(1);
	}

	if (head == NULL)
	{
		head = newmanager;
	}
	else
	{
		//找到尾节点
		book* pcur = head;
		while (pcur->next)
		{
			pcur = pcur->next;
		}
		pcur->next = newmanager;
	}

	printf("请输入管理员编号:");
	scanf("%d", &(newmanager->M_ID));
	printf("请输入管理员账号:");
	scanf("%s", newmanager->M_Account);
	printf("请输入管理员密码:");
	scanf("%s", newmanager->M_Password);

	char sql[256];
	sprintf(sql, "insert into manager values('%d','%s','%s')",
		newmanager->M_ID, newmanager->M_Account, newmanager->M_Password);
	mysql_query(mysql, sql);

	newmanager->next = NULL;
	printf("添加成功!
");
	return head;
}

//展示书籍信息
void Show_All_book(book* head)
{
	book* p = head;
	printf("===================================================================================
");
	printf("|书名                    |作者            |出版社          |价格  |库存  |编号    |
");
	while (p != NULL) {
		printf("-----------------------------------------------------------------------------------
");
		printf("|%-24s|%-16s|%-16s|%-6.2f|%-6d|%-8d|
", p->B_NAME, p->Author, p->Publish, p->Price, p->Quantity, p->B_ID);
		p = p->next;
	}
	printf("===================================================================================
");

}
//查找书籍信息
void Search_book(book* head)
{
	book* p = head;
	char search[100];
	int option;
	printf("=======================
");
	printf("|   请输入查询的项目  |
");
	printf("|    1.图书名         |
");
	printf("|    2.书作者         |
");
	printf("|    3.出版社         |
");
	printf("=======================
");
	scanf("%d", &option);
	while (1)
	{
		printf("=======================
");
		printf("|   请输入查询的内容   |
");
		printf("=======================
");
		scanf("%s", search);
		printf("===================================================================================
");
		printf("|书名                    |作者            |出版社          |价格  |库存  |编号    |
");

		int flag = 1;
		while (p != NULL)
		{
			switch (option)
			{
			case 1:
				if (strstr(p->B_NAME, search))
				{
					flag = 0;
					printf("-----------------------------------------------------------------------------------
");
					printf("|%-24s|%-16s|%-16s|%-6.2f|%-6d|%-8d|
", p->B_NAME, p->Author, p->Publish, p->Price, p->Quantity, p->B_ID);
				}
				break;
			case 2:
				if (strstr(p->Author, search))
				{
					flag = 0;
					printf("-----------------------------------------------------------------------------------
");
					printf("|%-24s|%-16s|%-16s|%-6.2f|%-6d|%-8d|
", p->B_NAME, p->Author, p->Publish, p->Price, p->Quantity, p->B_ID);
				}
				break;
			case 3:
				if (strstr(p->Publish, search))
				{
					flag = 0;
					printf("-----------------------------------------------------------------------------------
");
					printf("|%-24s|%-16s|%-16s|%-6.2f|%-6d|%-8d|
", p->B_NAME, p->Author, p->Publish, p->Price, p->Quantity, p->B_ID);
				}
				break;
			}
			p = p->next;
		}
		if (flag)
		{
			printf("-----------------------------------------------------------------------------------
");
			printf("|%-24s|%-16s|%-16s|%-6s|%-6s|%-8s|
", "无", "无", "无", "无", "无", "无");
		}

		printf("===================================================================================
");
		break;
	}
}
//删除书籍信息
book* Delete_Book(book* head, MYSQL* mysql)
{
	book* p = head;
	book* pcur = NULL;
	int id, option;
	char sql[256];
	printf("请输入删除书籍的编号:");
	scanf("%d", &id);
	while (p)
	{
		if (id == p->B_ID)
		{
			break;
		}
		pcur = p;
		p = p->next;
	}
	if (p == NULL)
	{
		printf("未找到此ID编号的书籍
");
		return 0;
	}
	else
	{
		printf("===================================================================================
");
		printf("|书名                    |作者            |出版社          |价格  |库存  |编号    |
");
		printf("-----------------------------------------------------------------------------------
");
		printf("|%-24s|%-16s|%-16s|%-6.2f|%-6d|%-8d|
", p->B_NAME, p->Author, p->Publish, p->Price, p->Quantity, p->B_ID);
		printf("===================================================================================
");

		printf("================
");
		printf("|是否确定删除?|
");
		printf("|0.取消  1.确定|
");
		printf("================
");

		scanf("%d", &option);
		switch (option)
		{
		case 1:
			sprintf(sql, "delete from book where B_ID = %d;", id);
			mysql_query(mysql, sql);
			if (p == head)
			{
				head = head->next;
				free(p);
			}
			else
			{
				pcur->next = p->next;
				free(p);
			}
			printf("已成功删除
");
			option = 0;
			break;
		case 0:
			printf("取消删除
");
			break;
		default:
			printf("输入错误
");
			break;
		}
	}
	return head;
}
//修改书籍信息
book* Change_book(book* head, MYSQL* mysql)
{
	int id;
	int option = 0;
	book* p = head;
	char sql[256];
	printf("请输入你要修改的书籍编号:");
	scanf("%d", &id);
	while (p)
	{
		if (id == p->B_ID)
		{
			break;
		}
		p = p->next;
	}
	if (p == NULL)
	{
		printf("未找到此ID编号的书籍
");
		return 0;
	}
	else
	{
		do
		{
			printf("===================================================================================
");
			printf("|书名                    |作者            |出版社          |价格  |库存  |编号    |
");
			printf("-----------------------------------------------------------------------------------
");
			printf("|%-24s|%-16s|%-16s|%-6.2f|%-6d|%-8d|
", p->B_NAME, p->Author, p->Publish, p->Price, p->Quantity, p->B_ID);
			printf("===================================================================================
");

			printf("================
");
			printf("|请选择修改的内容|
");
			printf("|     1.书名    |
");
			printf("|     2.作者    |
");
			printf("|    3.出版社   |
");
			printf("|     4.价格    |
");
			printf("|    5.库存量   |
");
			printf("|   0.退出修改  |
");
			printf("================
");
			scanf("%d", &option);

			switch (option)
			{
			case 1:
				printf("请输入修改后的书名:");
				scanf("%s", p->B_NAME);
				break;

			case 2:
				printf("请输入修改后的作者:");
				scanf("%s", p->Author);
				break;

			case 3:
				printf("请输入修改后的出版社:");
				scanf("%s", p->Publish);
				break;

			case 4:
				printf("请输入修改后的价格:");
				scanf("%f", &(p->Price));
				break;

			case 5:
				printf("请输入修改后的库存量:");
				scanf("%d", &(p->Quantity));
				break;
			case 0:
				break;
			}
		} while (option);
	}

	sprintf(sql, "update book set B_NAME = '%s', Author = '%s', Publish = '%s', Price = %f, Quantity = %d where B_ID = %d;",
		p->B_NAME, p->Author, p->Publish, p->Price, p->Quantity, p->B_ID);
	mysql_query(mysql, sql);

	printf("修改成功!
");
	return 0;
}

//展示所有的用户信息
void Show_All_user(user* head)
{
	user* p = head;
	printf("=========================================================
");
	printf("|用户编号                   |账号          |密码          |
");
	while (p != NULL) {
		printf("---------------------------------------------------------
");
		printf("|%-27d|%-14s|%-14s|
", p->U_ID, p->U_Account, p->U_Password);
		p = p->next;
	}
	printf("=========================================================
");
}
//从数据库中加载用户信息
user* load_User(user* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql)
{
	user* p = NULL, * pr = head;
	mysql_query(mysql, "select * from user;");
	res = mysql_store_result(mysql);

	while (row = mysql_fetch_row(res))
	{
		p = NULL, pr = head;
		p = (user*)malloc(sizeof(user));
		if (p == NULL)
		{
			perror("malloc fail");
			exit(1);
		}
		if (head == NULL)
		{
			head = p;
		}
		else
		{
			while (pr->next != NULL)
			{
				pr = pr->next;
			}
			pr->next = p;
		}
		p->U_ID = atoi(row[0]);
		strcpy(p->U_Account, row[1]);
		strcpy(p->U_Password, row[2]);
		p->next = NULL;
	}

	mysql_free_result(res);

	return head;
}
//从数据库中加载管理员信息
user* load_Manager(user* head, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql)
{
	manager* p = NULL, * pr = head;
	mysql_query(mysql, "select * from manager;");
	res = mysql_store_result(mysql);

	while (row = mysql_fetch_row(res))
	{
		p = NULL, pr = head;
		p = (manager*)malloc(sizeof(manager));
		if (p == NULL)
		{
			perror("malloc fail");
			exit(1);
		}
		if (head == NULL)
		{
			head = p;
		}
		else
		{
			while (pr->next != NULL)
			{
				pr = pr->next;
			}
			pr->next = p;
		}
		p->M_ID = atoi(row[0]);
		strcpy(p->M_Account, row[1]);
		strcpy(p->M_Password, row[2]);
		p->next = NULL;
	}

	mysql_free_result(res);

	return head;
}
//修改用户密码
int Change_User_password(user* head, MYSQL* mysql)
{
	char account[30];
	char password[30];
	char sql[256];
	int option;
	user* p = head;
	printf("请输入用户账号:");
	scanf("%s", account);
	while (p)
	{
		if (!strcmp(account, p->U_Account))
		{
			break;
		}
		p = p->next;
	}

	if (p == NULL)
	{
		printf("没有查找到该用户
");
		return 0;
	}
	else
	{
		printf("==============================
");
		printf("|账号                |编号  |
");
		printf("------------------------------
");
		printf("|%-20s|%6d|
", p->U_Account, p->U_ID);
		printf("==============================
");
	}

	while (1)
	{
		printf("请输入该账号密码:");
		scanf("%s", password);
		if (strcmp(password, p->U_Password) == 0)
		{
			printf("请输入新密码:");
			scanf("%s", password);
			sprintf(sql, "update user set U_Password = '%s' where U_ID = %d;", password, p->U_ID);
			mysql_query(mysql, sql);
			printf("修改成功!");
			break;
		}
		else
		{
			printf("密码错误,请重试
");
		}
	}
}
//用户登陆
user* user_Login(user* head)
{
	user* p = head;
	char account[30], password[30];
	printf("请输入账号:");
	scanf("%s", account);
	while (p != NULL)
	{
		if (!strcmp(account, p->U_Account))
		{
			break;
		}
		p = p->next;
	}
	if (p == NULL)
	{
		printf("没有查找到该账号!
");
		return 0;
	}
	else
	{
		while (1)
		{
			printf("请输入密码:");
			scanf("%s", password);
			if (strcmp(password, p->U_Password) == 0)
			{
				printf("成功登录!
");
				break;
			}
			else {
				printf("密码错误!请重新输入!
");
			}
		}
	}

	return p;
}
//管理员登录
manager* manager_Login(manager* head)
{
	manager* p = head;
	char account[30], password[30];
	printf("请输入账号:");
	scanf("%s", account);
	while (p != NULL)
	{
		if (!strcmp(account, p->M_Account))
		{
			break;
		}
		p = p->next;
	}
	if (p == NULL)
	{
		printf("没有查找到该账号!
");
		return NULL;
	}
	else
	{
		while (1)
		{
			printf("请输入密码:");
			scanf("%s", password);
			if (strcmp(password, p->M_Password) == 0)
			{
				printf("成功登录!
");
				break;
			}
			else {
				printf("密码错误!请重新输入!
");
			}
		}
	}

	return p;
}

//显示有库存的书籍
void Show_remaining_book(MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql)
{
	mysql_query(mysql, "select * from book;");
	res = mysql_store_result(mysql);
	printf("===================================================================================
");
	printf("|书名                    |作者            |出版社          |库存量         |编号    
");
	while (row = mysql_fetch_row(res)) {
		//若余量大于0则输出
		if (atoi(row[5]) > 0) {
			printf("-----------------------------------------------------------------------------------
");
			printf("|%-24s|%-16s|%-16s|%-15d|%-8d
", row[1], row[2], row[3], atoi(row[5]), atoi(row[0]));
		}
	}
	printf("===================================================================================
");
}
//借阅图书
int borrow_book(int id, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql, book* head)
{
	Show_remaining_book(res, row, mysql);
	char sql[256];
	int b_id;
	book* p = head;
	printf("请输入要借阅的书籍编号:");
	scanf("%d", &b_id);

	while (head != NULL)
	{
		if (b_id == p->B_ID)
		{
			sprintf_s(sql, sizeof(sql), "select * from book where B_ID = %d;", b_id);
			mysql_query(mysql, sql);
			res = mysql_store_result(mysql);
			row = mysql_fetch_row(res);
			if (atoi(row[5]) <= 0)
			{
				printf("库存量不足!
");
				return 0;
			}
			else
			{
				time_t rawtime;
				struct tm* timeinfo;
				char date_str[11]; // 足够存储 "YYYY-MM-DD" 格式的日期字符串

				// 获取当前时间的时间戳
				time(&rawtime);

				// 将时间戳转换为本地时间
				timeinfo = localtime(&rawtime);

				// 使用sprintf将年、月、日格式化为字符串
				// 注意:tm_year是从1900年开始的,所以需要+1900
				// tm_mon是从0开始的,所以需要+1
				sprintf(date_str, "%d-%02d-%02d",
					timeinfo->tm_year + 1900,
					timeinfo->tm_mon + 1,
					timeinfo->tm_mday);

				sprintf(sql, "insert into borrow_book values (%d,%d,'%s','%s','%s');", id, b_id, date_str, "NULL", "BORROWED");
				mysql_query(mysql, sql);
				sprintf(sql, "update book set Quantity = Quantity - 1 where B_ID = %d;", b_id);
				mysql_query(mysql, sql);
				printf("借阅成功!
");
				return 0;
			}
		}
		p = p->next;
	}
	if (p == NULL) {
		printf("图书编号不存在
");
	}

	return 0;
}
//归还图书
int return_book(int id, MYSQL_RES* res, MYSQL_ROW row, MYSQL* mysql, book* head)
{
	int b_id;
	book* p = head;
	char sql[256];
	printf("请输入要归还的书籍编号:");
	scanf("%d", &b_id);
	while (p != NULL)
	{
		if (b_id == p->B_ID)
		{
			time_t rawtime;
			struct tm* timeinfo;
			char date_str[11];
			time(&rawtime);
			timeinfo = localtime(&rawtime);
			sprintf(date_str, "%d-%02d-%02d",
				timeinfo->tm_year + 1900,
				timeinfo->tm_mon + 1,
				timeinfo->tm_mday);
			sprintf(sql, "update book set Quantity = Quantity + 1 where B_ID = %d;", p->B_ID);
			mysql_query(mysql, sql);
			sprintf(sql, "update borrow_book set Return_time = '%s', State = '%s' where U_ID = %d AND B_ID = %d;"
				, date_str, "RETURNED", id, p->B_ID);
			mysql_query(mysql, sql);
			printf("归还成功!
");
			break;
		}
		p = p->next;
	}
	if (p == NULL) 
	{
		printf("不存在该借出的图书!
");
	}

	return 0;
}

源文件:Test.c

在该文件前要定义自己的数据库数据:

Test02()
{
	MYSQL_RES* res = NULL;//查询结果集
	MYSQL_ROW row = NULL;//记录结构体


	//初始化
	MYSQL* con = mysql_init(NULL);

	//设置字符编码,以防出现乱码
	mysql_options(con, MYSQL_SET_CHARSET_NAME, "GBK");

	//开始连接
	if (!mysql_real_connect(con, host, use, password, database_name, port, NULL, 0))
	{
		fprintf(stderr, "connect fail", mysql_error(con));
		return -1;
	}
	book* book_head = NULL;
	user* user_head = NULL;
	manager* manager_head = NULL;


	book_head = load_Book(book_head, res, row, con);
	user_head = load_User(user_head, res, row, con);
	manager_head = load_Manager(manager_head, res, row, con);

	//主体


	
	int input = 0;
	do
	{
		Menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			if (manager_Login(manager_head))
			{
				int input2 = 0;
				do
				{
					manager_Menu();
					scanf("%d", &input2);
					switch (input2)
					{
					case 1:
						Add_new_book(book_head, con);
						break;
					case 2:
						Show_All_book(book_head);
						break;
					case 3:
						Search_book(book_head);
						break;
					case 4:
						Change_book(book_head,con);
						break;
					case 5:
						Delete_Book(book_head, con);
						break;
					case 6:
						Show_All_user(user_head);
						break;
					case 7:
						input2 = 0;
						break;
					case 8:
						Add_new_manager(manager_head, con);
						break;
					case 0:
						input2 = 0;
						input = 0;
						break;
					}
				} while (input2);
			}
			break;
		case 2:
			printf("
");
			user * cur = user_Login(user_head);
			if (cur)
			{
				int input3 = 0;
				do
				{
					reader_Menu(user_head);
					scanf("%d", &input3);
					switch (input3)
					{
					case 1:
						borrow_book(cur->U_ID, res, row, con, book_head);
						break;
					case 2:
						return_book(cur->U_ID, res, row, con, book_head);
						break;
					case 3:
						Change_User_password(user_head, con);
						break;
					case 4:
						input3 = 0;
						break;
					case 0:
						input3 = 0;
						input = 0;
						break;
					}

				} while (input3);
			}
			break;
		case 3:
			Add_new_user(user_head, con);
			break;
		}
	} while (input);
	
	printf("再会!
");

	//关闭连接
	mysql_close(con);
}

int main()
{
	//Test01();
	Test02();

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2307911.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VSCode轻松调试运行C#控制台程序

1.背景 我一直都是用VS来开发C#项目的&#xff0c;用的比较顺手&#xff0c;也习惯了。看其他技术文章有介绍VS Code更轻量&#xff0c;更方便。所以我专门花时间来使用VS Code&#xff0c;看看它是如何调试代码、如何运行C#控制台。这篇文章是一个记录的过程。 2.操作 2.1 V…

python-leetcode-下一个排列

31. 下一个排列 - 力扣&#xff08;LeetCode&#xff09; class Solution:def nextPermutation(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""# Step 1: Find the first decreasing element …

Jsmoke-一款强大的js检测工具,浏览器部署即用,使用方便且高效

目录标题 Jsmoke &#x1f6ac;&#x1f6ac; by Yn8rt使用方式界面预览功能特性支持的敏感信息类型 Jsmoke &#x1f6ac;&#x1f6ac; by Yn8rt ​ 该插件由 Yn8rt师傅 开发&#xff0c;插件可以理解为主动版的hae和apifinder&#xff0c;因为其中的大多数规则我都引用了&a…

iphone上ios设备开启safari开发者debug模式,配合mac电脑使用

1.mac操作 mac的safari上打开开发者模式&#xff0c;打开显示网页开发者功能 2.开启IPhone的Safari调试模式 启用 Web 检查 功能&#xff0c;打开 iPhone 依次进入 设置 > Safari浏览器 > 高级 > 网页检查器 > 启用。 3.调试步骤 先用IPhone 的Safari打开要调试…

Datawhale 数学建模导论二 笔记5 多模数据与智能模型

主要涉及到的知识点有&#xff1a; 数字图像处理与计算机视觉 计算语言学与自然语言处理 数字信号处理与智能感知 10.1 数字图像处理与计算机视觉 视觉信息是我们第一种非常规的数据模式&#xff0c;在Python当中可以使用opencv处理数字图像&#xff0c;并提取出视觉特征用…

如何在一台服务器上搭建 mongodb副本集1主2从节点

在一台服务器上搭建 MongoDB 副本集&#xff08;1 主节点 2 从节点&#xff09;可以通过运行多个 MongoDB 实例并使用不同端口和数据目录来实现。以下是详细步骤&#xff1a; 1. 准备工作 确保已安装 MongoDB。为每个实例创建独立的数据目录和日志文件。 2. 创建数据目录和…

TikTok隐私保护措施:确保用户安全

TikTok隐私保护措施&#xff1a;确保用户安全 在这个信息爆炸的时代&#xff0c;社交媒体平台的隐私保护问题日益成为公众关注的焦点。TikTok&#xff0c;作为全球领先的短视频平台&#xff0c;拥有庞大的用户群体&#xff0c;因此&#xff0c;其隐私保护措施显得尤为重要。本…

Apollo Cyber 学习笔记

目录 0 Introduction What Why Advantage 1 Example 2 Concept 3 Flow Chart 4 Module 4.1 Transport 4.1.1 Share Memory 4.1.1.1 Segment 4.1.1.1.1 State 4.1.1.1.2 Block 4.1.1.1.3 Common 4.1.1.2 Notifier 4.1.1.2.1 ConditionNotifier 4.1.1.2.2 Multi…

mamba_ssm和causal-conv1d详细安装教程

1.前言 Mamba是近年来在深度学习领域出现的一种新型结构&#xff0c;特别是在处理长序列数据方面表现优异。在本文中&#xff0c;我将介绍如何在 Linux 系统上安装并配置 mamba_ssm 虚拟环境。由于官方指定mamba_ssm适用于 PyTorch 版本高于 1.12 且 CUDA 版本大于 11.6 的环境…

Ruby基础

一、字符串 定义 283.to_s //转为string "something#{a}" //定义字符串&#xff0c;并且插入a变量的值 something//单引号定义变量 %q(aaaaaaaaa) // 定义字符串&#xff0c;&#xff08;&#xff09;内可以是任何数&#xff0c;自动转义双引号%Q("aaaaa"…

Flutter的permission_handler插件检查iOS的通知权限不准确

今天&#xff0c;做好了一个功能&#xff0c;就是在app内检查用户有没有给当前APP打开通知权限&#xff0c; 如果没打开&#xff0c;就展示一个 banner &#xff0c;让用户去点击banner去打开权限 。 android上测试得非常顺利&#xff0c; 结果&#xff0c; 在iOS 上就是不…

vue使用a-table设置自定义合并字段实现某字段值相同则合并行

背景&#xff1a; 笔者前端使用ant-design-vue,二次开发了a-table,但a-table组件的属性方法都可以用&#xff1b; 业务需求&#xff1a;物资存放在不同的仓库&#xff0c;显示物资统计表格&#xff0c;以物资分组合并显示物资名称、总数量&#xff08;物资A在所有库房总数量&a…

Docker容器日常维护常用命令大全

友情提示&#xff1a;本文内容由银河易创&#xff08;https://ai.eaigx.com&#xff09;AI创作平台deepseek-v3模型生成&#xff0c;文中所有命令未进行验证&#xff0c;仅供参考。请根据具体情况和需求进行适当的调整和验证。 引言 Docker作为当前最流行的容器化技术&#xf…

《昇腾推理服务器+DeepSeek大模型》技术培训在图为科技成功举办

2月17日&#xff0c;华为政企业务团队受邀莅临图为科技深圳总部&#xff0c;并成功举办了一场聚焦于《昇腾推理服务器DeepSeek大模型》的专业知识培训。 此次培训活动不仅深化了双方的技术交流&#xff0c;更标志着昇腾AI与DeepSeek大模型的全面融合应用即将迈入实质性落地的新…

DeepSeek开源周Day5: 3FS存储系统与AI数据处理新标杆

项目地址&#xff1a; GitHub - deepseek-ai/3FS: A high-performance distributed file system designed to address the challenges of AI training and inference workloads.GitHub - deepseek-ai/smallpond: A lightweight data processing framework built on DuckDB and…

FastAPI系列:如何配置跨域访问(CORS)

默认情况下&#xff0c;FastAPI应用程序不允许来自不同来源的请求。当你有一个前端应用程序与后端API通信&#xff0c;并且它们托管在不同的域或端口上时&#xff0c;在FastAPI中允许来自不同来源的请求是一种常见的场景。这被称为CORS&#xff08;跨域资源共享&#xff09;&am…

Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存

Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存 目录 Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存 一、简单介绍 二、简单介绍 camera 三、安装 camera 四、简单案例实现 五、关键代码 一、简单…

【Vue3 Teleport 技术解析:破解弹窗吸附与滚动列表的布局困局】

&#x1f31f; Vue3 Teleport 技术解析&#xff1a;破解弹窗吸附与滚动列表的布局困局 &#x1f30d; 背景&#xff1a;传统组件嵌套的布局之痛 在传统前端开发中&#xff0c;组件往往被严格限制在父级 DOM 结构中&#xff0c;这导致三大典型问题&#xff1a; 层级监禁 &…

VBA技术资料MF276:在集合中使用键

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

安装Git(小白也会装)

一、官网下载&#xff1a;Git 1.依次点击&#xff08;红框&#xff09; 不要安装在C盘了&#xff0c;要炸了&#xff01;&#xff01;&#xff01; 后面都 使用默认就好了&#xff0c;不用改&#xff0c;直接Next&#xff01; 直到这里&#xff0c;选第一个 这两种选项的区别如…