第一百一十天学习记录:C++实战:自我设计用单链表、多态和文件操作写一个公会人员管理系统

本文主要是介绍第一百一十天学习记录:C++实战:自我设计用单链表、多态和文件操作写一个公会人员管理系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实现程序界面展示:

主界面:

在这里插入图片描述

程序输入非正常字符情况保护

在这里插入图片描述
在这里插入图片描述

添加会员信息

在这里插入图片描述

删除会员信息

在这里插入图片描述

查找会员信息

在这里插入图片描述

变更会员会阶

在这里插入图片描述

显示所有会员

在这里插入图片描述

排序会员信息

在这里插入图片描述

查看种族职业

在这里插入图片描述

保存信息的txt文件

在这里插入图片描述

工程文件目录

在这里插入图片描述

main.cpp代码

#include "allmember.h"
#include "alljob.h"
#include "allrace.h"
#include "allrank.h"enum Job
{EXI,//退出ADD,//添加LIS,//显示DEL,//删除MOD,//编辑SER,//查找SOR,//排序CHE //团队
};const int Orcjob[6] = { 1,2,3,4,9,10 };
const int Trolljob[7] = { 1,2,3,4,5,8,10 };
const int Taurenjob[5] = { 1,2,3,6,10 };
const int Forsakenjob[6] = { 1,4,5,8,9,10 };
const int BloodElfjob[7] = { 2,4,5,7,8,9,10 };
const int Humanjob[7] = { 1,4,5,7,8,9,10 };
const int Dwarfjob[6] = { 1,2,4,7,8,10 };
const int Gnomejob[5] = { 1,4,5,9,10 };
const int NightElfjob[6] = { 1,2,4,6,8,10 };
const int Draeneijob[7] = { 1,2,3,5,7,8,10 };void showtable()
{cout << "*****************************************" << endl;cout << "**********公会职业信息管理系统***********" << endl;cout << "*****************************************" << endl;cout << "************1、 添加会员信息*************" << endl;cout << "************2、 显示所有会员*************" << endl;cout << "************3、 删除会员信息*************" << endl;cout << "************4、 变更会员会阶*************" << endl;cout << "************5、 查找会员信息*************" << endl;cout << "************6、 排序会员信息*************" << endl;cout << "************7、 查看种族职业*************" << endl;cout << "************0、 退出管理系统*************" << endl;cout << "*****************************************" << endl;cout << "***请输入您所需要的操作选项,按回车确认:" << endl;
}Allmember* newmember(int Id,string Name,int Sex,int woker,int race,int rank)
{Worker* tmpwoker = NULL;Race* tmprace = NULL;GuildRank* tmprank = NULL;switch (woker){case 1:tmpwoker = new Warrior;break;case 2:tmpwoker = new Hunter;break;case 3:tmpwoker = new Shaman;break;case 4:tmpwoker = new Rogue;break;case 5:tmpwoker = new Mage;break;case 6:tmpwoker = new Druid;break;case 7:tmpwoker = new Paladin;break;case 8:tmpwoker = new Priest;break;case 9:tmpwoker = new Warlock;break;case 10:tmpwoker = new DeathKnight;break;default:break;}switch (race){case 1:tmprace = new Orc;break;case 2:tmprace = new Troll;break;case 3:tmprace = new Tauren;break;case 4:tmprace = new Forsaken;break;case 5:tmprace = new BloodElf;break;case 6:tmprace = new Human;break;case 7:tmprace = new Dwarf;break;case 8:tmprace = new Gnome;break;case 9:tmprace = new NightElf;break;case 10:tmprace = new Draenei;break;default:break;}switch (rank){case 1:tmprank = new President;break;case 2:tmprank = new Official;break;case 3:tmprank = new Elite;break;case 4:tmprank = new Member;break;case 5:tmprank = new Intern;break;default:break;}string m_Sex;if (Sex == 1){m_Sex = "男";}else{m_Sex = "女";}Allmember* ptemp = new Allmember(Id, Name, m_Sex, tmpwoker, tmprace, tmprank);ptemp->p_next = NULL;return ptemp;
}void read_member(Allmember* phead)
{ifstream ifs;ifs.open(FILENAME, ios::in);if (!ifs.is_open()){ifs.close();return;}char ch;ifs >> ch;if (ifs.eof()){ifs.close();return;}ifs.seekg(0, ios::beg);//因为在前面判断数据库是否为空的时候ifs移动了一个字符,因此这里需要将ifs指向置为初始int Id;string Name;int Sex;int worker;int race;int rank;while (ifs >> Id&&ifs >> Name&&ifs >> Sex&&ifs >> worker&&ifs >> race&&ifs >> rank){Allmember* pnew = newmember(Id,Name,Sex,worker,race,rank);phead->p_next = pnew;phead = pnew;}ifs.close();
}Allmember* initList()
{int Id = 0;string Name = "";string Sex = "";Worker* worker = NULL;Race* race = NULL;GuildRank* rank = NULL;Allmember* member = new Allmember(1, Name, Sex, worker, race, rank);member->p_next = NULL;return member;
}void showallmember(Allmember* phead)
{while (phead->p_next){phead->p_next->showInfo();phead = phead->p_next;}
}void savemember(Allmember* phead)
{int Id;string Name;int Sex;int worker;int race;int rank;ofstream ofs;ofs.open(FILENAME, ios::out);while (phead->p_next){Id = phead->p_next->getId();Name = phead->p_next->getName();Sex = phead->p_next->getSex();worker = phead->p_next->getWorker();race = phead->p_next->getRace();rank = phead->p_next->getGuildRank();ofs << Id << " "<< Name << " "<< Sex << " "<< worker << " "<< race << " "<< rank << " " << endl;phead = phead->p_next;}ofs.close();
}bool checkId(int Id, Allmember* phead)
{while (phead->p_next){if (Id == phead->p_next->getId()){return false;}phead = phead->p_next;}return true;
}bool checkrank(Allmember* phead)
{while (phead->p_next){if (1 == phead->p_next->getGuildRank()){return false;}phead = phead->p_next;}return true;
}void addmember(Allmember* phead)
{int Id;string Name;int Sex;int worker;int race;int rank;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入新会员编号=>";cin >> Id;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (Id < 1 || Id > 9999){cout << "输入编号超出范围(1~9999),请重新输入。" << endl;continue;}bool isOk = checkId(Id, phead);if (isOk){break;}else{cout << "存在重复的编号,请重新输入。" << endl;continue;}}while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入新会员姓名=>";cin >> Name;if (cin.fail()) {cout << "输入内容错误,请重新输入!" << endl;cin.clear();continue;}break;}cout << "1、男  2、女" << endl;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入新会员性别=>";cin >> Sex;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (Sex < 1 || Sex > 2){cout << "输入性别选项超出范围(1~2),请重新输入。" << endl;continue;}break;}cout << "1、会长  2、官员  3、精英  4、会员  5、见习" << endl;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入新会员公会会阶=>";cin >> rank;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (rank < 1 || rank > 5){cout << "输入会阶选项超出范围(1~5),请重新输入。" << endl;continue;}if (rank == 1){bool isOk = checkrank(phead);if (isOk){break;}else{cout << "公会只允许一名会长,请重新输入。" << endl;continue;}}break;}cout << "1、兽人  2、巨魔  3、牛头人 4、被遗忘者  5、血精灵" << endl;cout << "6、人类  7、矮人  8、侏儒   9、暗夜精灵 10、德莱尼" << endl;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入新会员种族=>";cin >> race;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (race < 1 || race > 10){cout << "输入种族选项超出范围(1~10),请重新输入。" << endl;continue;}break;}switch (race){case 1:cout << "1、战士 2、猎人 3、萨满" << endl;cout << "4、潜行者 5、术士 6、死亡骑士" << endl;break;case 2:cout << "1、战士 2、猎人 3、萨满" << endl;cout << "4、潜行者 5、法师 6、牧师 7、死亡骑士" << endl;break;case 3:cout << "1、战士 2、猎人 3、萨满" << endl;cout << "4、德鲁伊 5、死亡骑士" << endl;break;case 4:cout << "1、战士 2、潜行者 3、法师" << endl;cout << "4、牧师 5、术士 6、死亡骑士" << endl;break;case 5:cout << "1、猎人 2、潜行者 3、法师" << endl;cout << "4、圣骑士 5、牧师 6、术士 7、死亡骑士" << endl;break;case 6:cout << "1、战士 2、潜行者 3、法师" << endl;cout << "4、圣骑士 5、牧师 6、术士 7、死亡骑士" << endl;break;case 7:cout << "1、战士 2、猎人 3、潜行者" << endl;cout << "4、圣骑士 5、牧师 6、死亡骑士" << endl;break;case 8:cout << "1、战士 2、潜行者 3、法师" << endl;cout << "4、术士 5、死亡骑士" << endl;break;case 9:cout << "1、战士 2、猎人 3、潜行者" << endl;cout << "4、德鲁伊 5、牧师 6、死亡骑士" << endl;break;case 10:cout << "1、战士 2、猎人 3、萨满" << endl;cout << "4、法师 5、圣骑士 6、牧师 7、死亡骑士" << endl;break;default:break;}while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入新会员职业=>";int chjob = 0;cin >> chjob;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}switch (race){case 1:if (chjob < 1 || chjob > 6){cout << "输入职业选项超出范围(1~6),请重新输入。" << endl;continue;}worker = Orcjob[chjob - 1];break;case 2:if (chjob < 1 || chjob > 7){cout << "输入职业选项超出范围(1~7),请重新输入。" << endl;continue;}worker = Trolljob[chjob - 1];break;case 3:if (chjob < 1 || chjob > 5){cout << "输入职业选项超出范围(1~5),请重新输入。" << endl;continue;}worker = Taurenjob[chjob - 1];break;case 4:if (chjob < 1 || chjob > 6){cout << "输入职业选项超出范围(1~6),请重新输入。" << endl;continue;}worker = Forsakenjob[chjob - 1];break;case 5:if (chjob < 1 || chjob > 7){cout << "输入职业选项超出范围(1~7),请重新输入。" << endl;continue;}worker = BloodElfjob[chjob - 1];break;case 6:if (chjob < 1 || chjob > 7){cout << "输入职业选项超出范围(1~7),请重新输入。" << endl;continue;}worker = Humanjob[chjob - 1];break;case 7:if (chjob < 1 || chjob > 6){cout << "输入职业选项超出范围(1~6),请重新输入。" << endl;continue;}worker = Dwarfjob[chjob - 1];break;case 8:if (chjob < 1 || chjob > 5){cout << "输入职业选项超出范围(1~5),请重新输入。" << endl;continue;}worker = Gnomejob[chjob - 1];break;case 9:if (chjob < 1 || chjob > 6){cout << "输入职业选项超出范围(1~6),请重新输入。" << endl;continue;}worker = NightElfjob[chjob - 1];break;case 10:if (chjob < 1 || chjob > 7){cout << "输入职业选项超出范围(1~7),请重新输入。" << endl;continue;}worker = Draeneijob[chjob - 1];break;default:break;}break;}Allmember* pnew = newmember(Id, Name, Sex, worker, race, rank);while (phead->p_next){phead = phead->p_next;}phead->p_next = pnew;cout << "成功添加一名新会员,新会员信息如下:" << endl;pnew->showInfo();
}void statistics(Allmember* phead)
{int total = 0;int sexarr[2] = { 0 };int rankarr[5] = { 0 };int racearr[10] = { 0 };int jobarr[10] = { 0 };while (phead->p_next){++total;if (1 == phead->p_next->getSex()){++sexarr[0];}else{++sexarr[1];}switch (phead->p_next->getGuildRank()){case 1:++rankarr[0];break;case 2:++rankarr[1];break;case 3:++rankarr[2];break;case 4:++rankarr[3];break;case 5:++rankarr[4];break;default:break;}switch (phead->p_next->getRace()){case 1:++racearr[0];break;case 2:++racearr[1];break;case 3:++racearr[2];break;case 4:++racearr[3];break;case 5:++racearr[4];break;case 6:++racearr[5];break;case 7:++racearr[6];break;case 8:++racearr[7];break;case 9:++racearr[8];break;case 10:++racearr[9];break;default:break;}switch (phead->p_next->getWorker()){case 1:++jobarr[0];break;case 2:++jobarr[1];break;case 3:++jobarr[2];break;case 4:++jobarr[3];break;case 5:++jobarr[4];break;case 6:++jobarr[5];break;case 7:++jobarr[6];break;case 8:++jobarr[7];break;case 9:++jobarr[8];break;case 10:++jobarr[9];break;default:break;}phead = phead->p_next;}cout << "***************公会统计信息***************" << endl;cout << "公会总人数:" << total << endl;cout << "公会男性会员:" << sexarr[0] << endl;cout << "公会女性会员:" << sexarr[1] << endl;cout << "------------------------------------------" << endl;cout << "公会会长人数:" << rankarr[0] << endl;cout << "公会官员人数:" << rankarr[1] << endl;cout << "公会精英人数:" << rankarr[2] << endl;cout << "公会会员人数:" << rankarr[3] << endl;cout << "公会见习人数:" << rankarr[4] << endl;cout << "------------------------------------------" << endl;cout << "公会  兽人  人数:" << racearr[0] << endl;cout << "公会  巨魔  人数:" << racearr[1] << endl;cout << "公会 牛头人 人数:" << racearr[2] << endl;cout << "公会被遗忘者人数:" << racearr[3] << endl;cout << "公会 血精灵 人数:" << racearr[4] << endl;cout << "公会  人类  人数:" << racearr[5] << endl;cout << "公会  矮人  人数:" << racearr[6] << endl;cout << "公会  侏儒  人数:" << racearr[7] << endl;cout << "公会暗夜精灵人数:" << racearr[8] << endl;cout << "公会 德莱尼 人数:" << racearr[9] << endl;cout << "------------------------------------------" << endl;cout << "公会  战士  人数:" << jobarr[0] << endl;cout << "公会  猎人  人数:" << jobarr[1] << endl;cout << "公会  萨满  人数:" << jobarr[2] << endl;cout << "公会 潜行者 人数:" << jobarr[3] << endl;cout << "公会  法师  人数:" << jobarr[4] << endl;cout << "公会 德鲁伊 人数:" << jobarr[5] << endl;cout << "公会 圣骑士 人数:" << jobarr[6] << endl;cout << "公会  牧师  人数:" << jobarr[7] << endl;cout << "公会  术士  人数:" << jobarr[8] << endl;cout << "公会死亡骑士人数:" << jobarr[9] << endl;cout << "***************公会统计信息***************" << endl;
}void search(Allmember* phead)
{int Id;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入需要查找的编号=>";cin >> Id;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}while (phead->p_next){if (phead->p_next->getId() == Id){phead->p_next->showInfo();return;}phead = phead->p_next;}break;}cout << "查无此人!" << endl;
}void deletemenber(Allmember* phead)
{cout << "注:输入0取消删除操作。" << endl;int Id;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入需要删除的编号=>";cin >> Id;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (0 == Id){cout << "已取消删除操作。" << endl;return;}while (phead->p_next){if (phead->p_next->getId() == Id){string Name = phead->p_next->getName();Allmember* deltemp;deltemp = phead->p_next;phead->p_next = phead->p_next->p_next;delete deltemp;cout << Name << "已退出公会!" << endl;return;}phead = phead->p_next;}break;}cout << "查无此人!" << endl;
}void modmenber(Allmember* phead)
{Allmember* truephead = phead;cout << "注:输入0取消删除操作。" << endl;int Id;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入需要变更职务的编号=>";cin >> Id;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (0 == Id){cout << "已取消变更操作。" << endl;return;}while (phead->p_next){if (phead->p_next->getId() == Id){int newrank;cout << "1、会长  2、官员  3、精英  4、会员  5、见习" << endl;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入新的公会会阶=>";cin >> newrank;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (0 == newrank){cout << "已取消变更操作。" << endl;return;}if (newrank < 1 || newrank > 5){cout << "输入会阶选项超出范围(1~5),请重新输入。" << endl;continue;}if (newrank == 1){bool isOk = checkrank(truephead);if (isOk){break;}else{cout << "公会只允许一名会长,请重新输入。" << endl;continue;}}break;}int oldrank = phead->p_next->getGuildRank();if (oldrank == newrank){cout << "新会阶与原会阶一样。" << endl;return;}int Sex = phead->p_next->getSex();int worker = phead->p_next->getWorker();int race = phead->p_next->getRace();string Name = phead->p_next->getName();Allmember* temp= phead->p_next->p_next;delete phead->p_next;phead->p_next = newmember(Id, Name, Sex, worker, race, newrank);phead->p_next->p_next = temp;if (oldrank > newrank){cout << Name << "已晋升" << endl;}else{cout << Name << "已降职" << endl;}return;}phead = phead->p_next;}break;}cout << "查无此人!" << endl;
}void sortmenber(Allmember* phead)
{Allmember* truephead = phead;cout << "1、按照编号升序排列。" << endl;cout << "2、按照编号降序排列。" << endl;cout << "注:输入0取消删除操作。" << endl;int sortmod;while (true){int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "请输入需要排序的模式=>";cin >> sortmod;if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (0 == sortmod){cout << "已取消变更操作。" << endl;return;}if (sortmod < 1 || sortmod > 2){cout << "输入选项超出范围(1~2),请重新输入。" << endl;continue;}break;}int total = 0;while (phead->p_next){++total;phead = phead->p_next;}if (total < 2){cout << "当前公会人数少于2人无法排序。" << endl;return;}phead = truephead;int* intarr = new int[total];Allmember** Allmemberarr = new Allmember* [total];int i = 0;while (phead->p_next){Allmemberarr[i] = phead->p_next;intarr[i] = phead->p_next->getId();++i;phead = phead->p_next;}int flag;for (int i = 0; i < total - 1; ++i){flag = 0;for (int j = 0; j < total - i - 1; ++j){if (sortmod == 1){if (intarr[j] > intarr[j + 1]){int tmp = intarr[j];intarr[j] = intarr[j + 1];intarr[j + 1] = tmp;Allmember* sorttemp = Allmemberarr[j];Allmemberarr[j] = Allmemberarr[j + 1];Allmemberarr[j + 1] = sorttemp;flag = 1;}}else{if (intarr[j] < intarr[j + 1]){int tmp = intarr[j];intarr[j] = intarr[j + 1];intarr[j + 1] = tmp;Allmember* sorttemp = Allmemberarr[j];Allmemberarr[j] = Allmemberarr[j + 1];Allmemberarr[j + 1] = sorttemp;flag = 1;}}}if (flag == 0){break;}}phead = truephead;for (int i = 0; i < total; ++i){phead->p_next = Allmemberarr[i];phead = phead->p_next;}phead->p_next = NULL;cout << "排序后结果:" << endl;showallmember(truephead);
}int main()
{showtable();Allmember* pHead = initList();Allmember* pQuit = NULL;read_member(pHead);int choice = 8;do {int availableChars = (int)cin.rdbuf()->in_avail();if (availableChars){cin.ignore(numeric_limits<streamsize>::max(), '\n');}cout << "主菜单选项=>" ;cin >> choice;system("cls");showtable();if (cin.fail()) {cout << "输入内容不是整数,请重新输入!" << endl;cin.clear();continue;}if (choice < 0 || choice> 7 ){cout << "输入数字超出范围,请重新输入。" << endl;continue;}switch (choice){case ADD:addmember(pHead);savemember(pHead);break;case LIS:showallmember(pHead);break;case DEL:deletemenber(pHead);savemember(pHead);break;case MOD:modmenber(pHead);savemember(pHead);break;case SER:search(pHead);break;case SOR:sortmenber(pHead);savemember(pHead);break;case CHE:statistics(pHead);break;default:break;}} while (choice);while (pHead){pQuit = pHead;pHead = pHead->p_next;delete pQuit;	}cout << "欢迎下次使用,再见。" << endl;return 0;
}

20230719修改:代码里有一处内存泄漏没有注意到。
在代码第974行(函数:void sortmenber(Allmember* phead)末尾)插入如下代码:

	showallmember(truephead);if (intarr != NULL){delete intarr;intarr = NULL;cout << "delete intarr" << endl;}if (Allmemberarr != NULL){delete Allmemberarr;Allmemberarr = NULL;cout << "delete Allmemberarr" << endl;}

这篇关于第一百一十天学习记录:C++实战:自我设计用单链表、多态和文件操作写一个公会人员管理系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/420872

相关文章

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND