C++ 开发篇+一个简单的数据库管理系统ZDB

说明:本文供数据库爱好者和初级开发人员学习使用
标签:数据库管理系统、RDBMS、小程序、C++、C++程序
系统:Windows 11 x86
CPU :Intel
IDE :Visual Studio 2022
语言:C++语言
标准:C++14
提示:如果您发现本文哪里写的有问题或者有更好的写法请留言或私信我进行修改优化


★ 程序界面

★ 功能简介

目前该C语言小程序实现了RDBMS上表的几个基础功能,如:
✔ DDL:create、drop、alter、truncate、flashback、rename、purge
✔ DML:insert、delete、update、select

★ 程序特点

✔ 程序会在首次运行时在同级创建一个目录用于存放数据库信息
✔ 程序运行期间表数据存储在内存中,类似于Redis
✔ 程序运行结束时会将表数据采用序列化方式存储为JSON格式落盘
✔ 程序采用vector实现表空间的动态调整
✔ 表在drop后purge前支持闪回,purge后相关空间可以复用
✔ 表记录在删除后只是标记为删除,方便后期复用并减少数据shrink的性能消化

★ 程序试用

https://download.csdn.net/download/zzt_2009/88971223

★ 使用案例

############【欢迎使用 ZDB】############
# 语言:C++              IDE :VS 2022 #
# 作者:zzt_2009         版本:V 6.0.0 #
# 主页:https://blog.csdn.net/zzt_2009 #
# [H/h]查看帮助          [E/e]退出程序 #
首次使用,正在初始化数据字典……
字典落盘成功!
字典文件初始化完成。
字典加载成功!
首次使用,正在初始化数据文件……
数据写入成功:写入了【1】个表
数据文件初始化完成。
首次使用,已为您显示帮助信息:
# L   For > list table def   #
# C   For > Create table     #
# D   For > Drop table       #
# A   For > Alter table      #
# R   For > Rename table     #
# T   For > Truncate table   #
# F   For > Flashback table  #
# P   For > Purge recyclebin #
# i   For > insert           #
# d   For > delete           #
# u   For > update           #
# s   For > select           #
# c   For > clear            #
# H/h For > help             #
# E/e For > exit             #
数据读取成功:加载了【1】个表
当前表空间:总大小为【1】,剩余空间【0】
SQL > L
# 库中所有状态的表信息如下
内存ID  表名 表状态 表编号 行数    列数
TMID[0] T0   STA[2] OID[0] ROWS[3] COLS[2]
# STA列值:1>新/空表、2>有数据、3>已删除、4>可复用
SQL > C
请输入表名:T1
表空间已满,已自动扩容!
当前表空间大小为:2
请输入列的[数量]:2
请输入第[1]列的[名称]:ID
请输入第[2]列的[名称]:NAME
表TMID:1,表OID:2字典落盘成功!
数据写入成功:写入了【2】个表
SQL > C
请输入表名:T2
表空间已满,已自动扩容!
当前表空间大小为:3
请输入列的[数量]:2
请输入第[1]列的[名称]:ID
请输入第[2]列的[名称]:NAME
表TMID:2,表OID:3字典落盘成功!
数据写入成功:写入了【3】个表
SQL > D
请输入表名:T1
已删除
字典落盘成功!
数据写入成功:写入了【3】个表
SQL > A
请输入表名:T2
请输入CID(列号): 2
请输入字段新值: NAME2
# 更新后表结构和数据如下:
R[00] RMID[00] : ID     NAME2
# Selected:[0]ROWS,[2]COLS
字典落盘成功!
数据写入成功:写入了【3】个表
SQL > F
请输入表OID: 1
表已闪回
字典落盘成功!
数据写入成功:写入了【3】个表
SQL > L
# 库中所有状态的表信息如下
内存ID  表名 表状态 表编号 行数    列数
TMID[0] T0   STA[2] OID[0] ROWS[3] COLS[2]
TMID[1] 1    STA[1] OID[1] ROWS[0] COLS[2]
TMID[2] T2   STA[1] OID[2] ROWS[0] COLS[2]
# STA列值:1>新/空表、2>有数据、3>已删除、4>可复用
SQL > R
请输入表名:1
请输入新名:T1
# 更新成功:
# 库中所有状态的表信息如下
内存ID  表名 表状态 表编号 行数    列数
TMID[0] T0   STA[2] OID[0] ROWS[3] COLS[2]
TMID[1] T1   STA[1] OID[1] ROWS[0] COLS[2]
TMID[2] T2   STA[1] OID[2] ROWS[0] COLS[2]
# STA列值:1>新/空表、2>有数据、3>已删除、4>可复用
字典落盘成功!
数据写入成功:写入了【3】个表
SQL > D
请输入表名:T1
已删除
字典落盘成功!
数据写入成功:写入了【3】个表
SQL > L
# 库中所有状态的表信息如下
内存ID  表名 表状态 表编号 行数    列数
TMID[0] T0   STA[2] OID[0] ROWS[3] COLS[2]
TMID[1] T1   STA[3] OID[1] ROWS[0] COLS[2]
TMID[2] T2   STA[1] OID[2] ROWS[0] COLS[2]
# STA列值:1>新/空表、2>有数据、3>已删除、4>可复用
SQL > P
回收站已清空!
字典落盘成功!
数据写入成功:写入了【3】个表
SQL > L
# 库中所有状态的表信息如下
内存ID  表名 表状态 表编号 行数    列数
TMID[0] T0   STA[2] OID[0] ROWS[3] COLS[2]
TMID[1] T1   STA[4] OID[1] ROWS[0] COLS[2]
TMID[2] T2   STA[1] OID[2] ROWS[0] COLS[2]
# STA列值:1>新/空表、2>有数据、3>已删除、4>可复用
SQL > i
请输入表名:T2
请输入数据(列以空格分隔,新行输入';'结束):
Input > 1 a
Input > 2 b
Input > ;
插入结束!
字典落盘成功!
数据写入成功:写入了【3】个表
R[00] RMID[00] : ID     NAME2
R[01] RMID[01] : 1      a
R[02] RMID[02] : 2      b
# Selected:[2]ROWS,[2]COLS
SQL > s
请输入表名:T0
R[00] RMID[00] : TEL    NAME
R[01] RMID[01] : 110    Police
R[02] RMID[02] : 120    Ambulance
R[03] RMID[03] : 119    Fire
# Selected:[3]ROWS,[2]COLS
SQL > d
请输入表名:T0
请输入RMID(内存行号): 2
# RMID[2]已删除
# 删除后表数据如下:
R[00] RMID[00] : TEL    NAME
R[01] RMID[01] : 110    Police
R[02] RMID[03] : 119    Fire
# Selected:[2]ROWS,[2]COLS
字典落盘成功!
数据写入成功:写入了【3】个表
SQL > e
字典落盘成功!
数据写入成功:写入了【3】个表
#########【感谢使用 ZDB 再见!】#########D:\WorkSpace\C++\ZDB\x64\Debug\ZDB.exe (进程 24820)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

★ 程序源码

//引用头文件
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>  
#include <direct.h> 
#include <string>
#include <iostream> 
#include <vector> 
#include <fstream> 
#include <cstdio>  
#include <sstream>  
#include <nlohmann/json.hpp> //详情:https://github.com/nlohmann/jsonusing json = nlohmann::json;
using namespace std;//禁用部分警告
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)//使用宏定义代替相关内容
#define R 99  //行
#define C 99  //列
#define N 32  //名称
#define L 99  //长度
#define S 32  //SIZE
#define DefaultPATH ".\\ZDATA\\"//全局变量
int i, j, k = 0; //
int ts; //
int fr, fc = 0; //文件行数,文件列数
int rn, cn = 0; //行号、列号
int oid, noid = 0; //全局对象号、内存号
char g_temp[L]; //临时使用的字符串变量
char table_name[N]; //表名
char Path[L];
char dict_file[N] = "ZDB.dic"; //文件名
char data_file[N] = "ZDB.dat"; //文件名
typedef struct S_Dict { //字典:结构体int state;			//状态:0>未分配、1>有效、2>删除char name[N];		//名称char value[L];		//值char comment[L];	//描述
} S_Dict;
S_Dict g_dict[S];
class S_Table {//成员变量
public:int state;			 //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用string name;		 //名称int oid;			 //对象编号int rows;			 //行数int cols;			 //列数string record[R][C]; //数据&状态:"">未分配、H>字段名、A>可用、D>删除//成员方法to_json(),用于将S_Table实例转换为JSON对象json to_json() const {json j_record = json::array();for (int r = 0; r <= rows; ++r) {json j_row = json::array();for (int c = 0; c <= cols; ++c) {j_row.push_back(record[r][c]);}j_record.push_back(j_row);}return json{ {"state", state}, {"name", name}, {"oid", oid}, {"rows", rows}, {"cols", cols}, {"record", j_record} };}//成员方法from_json(),用于将JSON对象转换为S_Table实例static S_Table from_json(const json& j) {S_Table table;table.state = j["state"].get<int>();table.name = j["name"].get<std::string>();table.oid = j["oid"].get<int>();table.rows = j["rows"].get<int>();table.cols = j["cols"].get<int>();for (int r = 0; r <= table.rows; ++r) {for (int c = 0; c <= table.cols; ++c) {table.record[r][c] = j["record"][r][c];}}return table;}
};//函数声明
int Head(); //界面输出
int Body(vector<S_Table>& v_tables); //程序主体
int Bye(); //程序退出
int Help(); //
int Dir_Init(); //
int Dict_Init(); //
int Dict_Read(); //
int Dict_Write(); //
int Data_Init(vector<S_Table>& v_tables); //
int Data_Read(vector<S_Table>& v_tables); //
int Data_Write(vector<S_Table>& v_tables); //
int List_Table(vector<S_Table>& v_tables); //
int Select(string table_name, vector<S_Table>& v_tables); //
int Create(string table_name, vector<S_Table>& v_tables); //
int Drop(string table_name, vector<S_Table>& v_tables); //
int Alter(string table_name, vector<S_Table>& v_tables); //
int Flashback(int oid, vector<S_Table>& v_tables); //
int Purge(vector<S_Table>& v_tables); //
int Truncate(string table_name, vector<S_Table>& v_tables); //
int Rename(string table_name, vector<S_Table>& v_tables); //
int Insert(string table_name, vector<S_Table>& v_tables); //
int Delete(string table_name, vector<S_Table>& v_tables); //
int Update(string table_name, vector<S_Table>& v_tables); ////主函数
int main() {Head();Dict_Read();//根据表空间大小配置 vector 数组大小ts = atoi(g_dict[1].value);vector<S_Table> v_tables(ts);//往 vector 数组中读取数据Data_Read(v_tables);Body(v_tables);return 0;
}//函数定义
int Body(vector<S_Table>& v_tables) {//命令判断while (1) {printf("SQL > ");int n;n = _getch();printf("%c\n", (char)n); //输出按键switch (n) {case 76: // L -> list table definationList_Table(v_tables);break;case 67: // C -> createstd::cout << "请输入表名:";std::cin >> table_name;Create(table_name, v_tables);break;case 68: // D -> dropstd::cout << "请输入表名:";std::cin >> table_name;Drop(table_name, v_tables);break;case 65: // A -> alterstd::cout << "请输入表名:";std::cin >> table_name;Alter(table_name, v_tables);break;case 70: // F -> flashbackstd::cout << "请输入表OID: ";std::cin >> oid;Flashback(oid, v_tables);break;case 80: // P -> purgePurge(v_tables);break;case 84: // T -> truncatestd::cout << "请输入表名:";std::cin >> table_name;Truncate(table_name, v_tables);break;case 82: // R -> renamestd::cout << "请输入表名:";std::cin >> table_name;Rename(table_name, v_tables);break;case 105: // i -> insertstd::cout << "请输入表名:";std::cin >> table_name;Insert(table_name, v_tables);break;case 100: // d -> deletestd::cout << "请输入表名:";std::cin >> table_name;Delete(table_name, v_tables);break;case 117: // u -> updatestd::cout << "请输入表名:";std::cin >> table_name;Update(table_name, v_tables);break;case 115: // s -> selectstd::cout << "请输入表名:";std::cin >> table_name;Select(table_name, v_tables);break;case 99: // c -> clearHead();break;case 72:  // H -> helpcase 104: // h -> helpHelp();break;case 69:  // E -> exitcase 101: // e -> exitDict_Write();Data_Write(v_tables);Bye();exit(0);default:printf("命令不正确请重新输入,或按[H/h]查看帮助\n");break;}}
}int Update(string table_name, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && ((v_tables[i].state == 2) || (v_tables[i].state == 1))) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用//存在则继续处理std::cout << "请输入RMID(内存行号): ";std::cin >> rn;std::cout << "请输入CID(列号): ";std::cin >> cn;std::cout << "请输入字段新值: ";std::cin >> g_temp;if (v_tables[i].state == 1) {printf("# 空表,无法DML!\n");return 0;}if ((rn != 0) && (cn != 0) && (v_tables[i].record[rn][0] == "A")) { //数据&状态:"">未分配、H>字段名、A>可用、D>删除v_tables[i].record[rn][cn] = g_temp;printf("# 更新后表数据如下:\n");Select(table_name, v_tables);//写盘Dict_Write();Data_Write(v_tables);return 0;}printf("不容许DML的位置!\n");return 0;}i++;}printf("表不存在!\n");return 0;
}int Delete(string table_name, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && ((v_tables[i].state == 2) || (v_tables[i].state == 1))) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用if (v_tables[i].state == 1) {printf("# 空表,无法DML!\n");return 0;}std::cout << "请输入RMID(内存行号): ";std::cin >> rn;if (rn != 0) {v_tables[i].record[rn][0] = "D";printf("# RMID[%d]已删除\n", rn);printf("# 删除后表数据如下:\n");Select(table_name, v_tables);Dict_Write();Data_Write(v_tables);return 0;}printf("首行为列名不容许删除!\n");return 0;}i++;}printf("表不存在!\n");return 0;
}int Insert(string table_name, vector<S_Table>& v_tables) {size_t i = 0;while (i < v_tables.size() && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && (v_tables[i].state == 1 || v_tables[i].state == 2)) {int num_cols = v_tables[i].cols;cout << "请输入数据(列以空格分隔,新行输入';'结束):" << endl;string input_line;cin.ignore();cout << "Input > ";while (getline(cin, input_line) && input_line != ";") {stringstream ss(input_line);string item;rn = 1;cn = 1;while (rn < R) {if (v_tables[i].record[rn][0] == "D" || v_tables[i].record[rn][0].empty()) {break;}rn++;}if (rn >= R) {cerr << "表已满,无法插入更多数据。\n";return 0;}while (ss >> item) {if (cn <= num_cols) {v_tables[i].record[rn][cn++] = item;}else {cerr << "警告:列数超出预期,额外的数据已被忽略。\n";break;}}if (cn < num_cols + 1) {cerr << "提示:输入的列数少于预期,这行数据可能不完整。\n";}v_tables[i].record[rn][0] = "A";v_tables[i].state = 2;v_tables[i].rows = max(v_tables[i].rows, rn);cout << "Input > ";}cout << "插入结束!\n";//写盘Dict_Write();Data_Write(v_tables);Select(table_name, v_tables);return 1;}i++;}cout << "表不存在!\n";return 0;
}int Rename(string table_name, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && ((v_tables[i].state == 2) || (v_tables[i].state == 1))) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用std::cout << "请输入新名:";std::cin >> g_temp;j = 0;while ((j < v_tables.size()) && (v_tables[j].state != 0)) {if ((v_tables[j].name == g_temp) && ((v_tables[j].state == 1) || (v_tables[j].state == 2))) {printf("新表名已存在!\n");return 0;}j++;}v_tables[i].name = g_temp;printf("# 更新成功:\n");List_Table(v_tables);//写盘Dict_Write();Data_Write(v_tables);return 0;}i++;}printf("表不存在!\n");return 0;
}int Truncate(string table_name, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && ((v_tables[i].state == 2) || (v_tables[i].state == 1))) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用v_tables[i].state = 1;j = 1;while (v_tables[i].record[j][0].length() != 0) {v_tables[i].record[j][0] = "";j++;}v_tables[i].rows = 0;printf("表已清空\n");//写盘Dict_Write();Data_Write(v_tables);return 0;}i++;}printf("表不存在!\n");return 0;
}int Purge(vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if (v_tables[i].state == 3) {v_tables[i].state = 4;}i++;}printf("回收站已清空!\n");//写盘Dict_Write();Data_Write(v_tables);return 0;
}int Flashback(int oid, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].oid == oid) && (v_tables[i].state == 3)) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用if (v_tables[i].record[1][0].length() == 0) {v_tables[i].state = 1;}else {v_tables[i].state = 2;}_itoa_s(v_tables[i].oid, g_temp, L, 10);v_tables[i].name = g_temp;printf("表已闪回\n");//写盘Dict_Write();Data_Write(v_tables);return 0;}i++;}printf("表不存在或已被清理!\n");return 0;
}int Alter(string table_name, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && ((v_tables[i].state == 2) || (v_tables[i].state == 1))) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用std::cout << "请输入CID(列号): ";std::cin >> cn;std::cout << "请输入字段新值: ";std::cin >> g_temp;rn = 0;if (cn != 0) {v_tables[i].record[rn][cn] = g_temp;printf("# 更新后表结构和数据如下:\n");Select(table_name, v_tables);//写盘Dict_Write();Data_Write(v_tables);return 0;}printf("非列名位置不容许DDL!\n");return 0;}i++;}printf("表不存在!\n");return 0;
}int Select(string table_name, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && ((v_tables[i].state == 2) || (v_tables[i].state == 1))) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用j = 0;k = 0;rn = 0;while (v_tables[i].record[rn][0].length() != 0) {if (v_tables[i].record[rn][0] != "D") {cn = 0;printf("R[%02d] RMID[%02d] : ", k, rn);while (v_tables[i].record[rn][cn].length() != 0) {cout << v_tables[i].record[rn][cn + 1] << "\t";j++;cn++;}printf("\n");k++;}rn++;}rn = k - 1;cn = v_tables[i].cols;printf("# Selected:[%d]ROWS,[%d]COLS\n", rn, cn);return 0;}i++;}printf("表不存在!\n");return 0;
}int Create(string table_name, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && ((v_tables[i].state == 2) || (v_tables[i].state == 1))) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用printf("表已存在\n");goto label_Create_end;}i++;}i = 0;noid = atoi(g_dict[0].value);
label_Create_start:while (i < v_tables.size()) {if ((v_tables[i].state == 0) || (v_tables[i].state == 4)) {v_tables[i].state = 1;v_tables[i].oid = noid;v_tables[i].rows = 0;v_tables[i].cols = 0;v_tables[i].name = table_name;v_tables[i].record[0][0] = "H";printf("请输入列的[数量]:");cin >> v_tables[i].cols;for (j = 0; j < v_tables[i].cols; j++) {printf("请输入第[%d]列的[名称]:", j + 1);cin >> v_tables[i].record[0][j + 1];}noid++;_itoa_s(noid, g_temp, L, 10);strcpy_s(g_dict[0].value, L, g_temp);printf("表TMID:%d,表OID:%d", i, noid);j = 1;while (v_tables[i].record[j][0].length() != 0) {v_tables[i].record[j][0] = "";j++;}//写盘Dict_Write();Data_Write(v_tables);return 0;}i++;}ts = (atoi(g_dict[1].value) + 1);v_tables.resize(ts);_itoa_s(ts, g_temp, L, 10);strcpy_s(g_dict[1].value, L, g_temp);printf("表空间已满,已自动扩容!\n");printf("当前表空间大小为:%d\n", ts);goto label_Create_start;
label_Create_end:return 0;
}int Drop(string table_name, vector<S_Table>& v_tables) {i = 0;while ((i < v_tables.size()) && (v_tables[i].state != 0)) {if ((v_tables[i].name == table_name) && ((v_tables[i].state == 2) || (v_tables[i].state == 1))) { //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用v_tables[i].state = 3;printf("已删除\n");//写盘Dict_Write();Data_Write(v_tables);return 0;}i++;}printf("表不存在\n");return 0;
}int List_Table(vector<S_Table>& v_tables) {i = 0;printf("# 库中所有状态的表信息如下\n");printf("内存ID  表名 表状态 表编号 行数    列数\n");while ((i < v_tables.size()) && (v_tables[i].state != 0)) {cout << "TMID[" << i << "] "<< setw(4) << left << v_tables[i].name<< " STA[" << v_tables[i].state << "]"<< " OID[" << v_tables[i].oid << "]"<< " ROWS[" << v_tables[i].rows << "]"<< " COLS[" << v_tables[i].cols << "]" << endl;i++;}printf("# STA列值:1>新/空表、2>有数据、3>已删除、4>可复用\n");return 0;
}int Head() {system("CLS");printf("############【欢迎使用 ZDB】############\n");printf("# 语言:C++              IDE :VS 2022 #\n");printf("# 作者:zzt_2009         版本:V 6.0.0 #\n");printf("# 主页:https://blog.csdn.net/zzt_2009 #\n");printf("# [H/h]查看帮助          [E/e]退出程序 #\n");return 0;
}int Bye() {printf("#########【感谢使用 ZDB 再见!】#########\n");return 0;
}int Help() {printf("# L   For > list table def   #\n");printf("# C   For > Create table     #\n");printf("# D   For > Drop table       #\n");printf("# A   For > Alter table      #\n");printf("# R   For > Rename table     #\n");printf("# T   For > Truncate table   #\n");printf("# F   For > Flashback table  #\n");printf("# P   For > Purge recyclebin #\n");printf("# i   For > insert           #\n");printf("# d   For > delete           #\n");printf("# u   For > update           #\n");printf("# s   For > select           #\n");printf("# c   For > clear            #\n");printf("# H/h For > help             #\n");printf("# E/e For > exit             #\n");return 0;
}int Data_Write(vector<S_Table>& v_tables) {i = 0;json j_tables = json::array();for (const auto& table : v_tables) {if (v_tables[i].state != 0) {j_tables.push_back(table.to_json());i++;}}// 写入到磁盘std::ofstream file(DefaultPATH + string(data_file));if (file.is_open()) {file << j_tables.dump(4);file.close();cout << "数据写入成功:写入了【" << i << "】个表" << endl;return 0;}else {cerr << "无法打开文件" << endl;}return 0;
}int Data_Read(vector<S_Table>& v_tables) {
Data_Read_start:ifstream file(DefaultPATH + string(data_file));if (file.is_open()) {json j_tables;file >> j_tables;file.close();size_t j = min(j_tables.size(), v_tables.size());size_t i;for (i = 0; i < j; ++i) {v_tables[i] = S_Table::from_json(j_tables[i]);}cout << "数据读取成功:加载了【" << i << "】个表" << endl;cout << "当前表空间:总大小为【" << v_tables.size() << "】,剩余空间【" << v_tables.size() - i << "】" << endl;return 0;}else {cout << "首次使用,正在初始化数据文件……" << endl;Dir_Init();Data_Init(v_tables);Data_Write(v_tables);printf("数据文件初始化完成。\n");//重新读取goto Data_Read_start;}
}int Dict_Write() {strcpy_s(Path, L, DefaultPATH);strcat_s(Path, L, dict_file);ofstream fp(Path, ios::binary);if (!fp) {cerr << "无法打开文件!" << endl;return 0;}fp.write(reinterpret_cast<const char*>(g_dict), sizeof(g_dict));fp.close();if (!fp.good()) {cerr << "发生错误,在写入文件时." << endl;}printf("字典落盘成功!\n");return 0;
}int Dict_Read() {strcpy_s(Path, L, DefaultPATH);strcat_s(Path, L, dict_file);
Dict_Read_start:ifstream fp(Path, ios::binary);if (!fp) {cout << "首次使用,正在初始化数据字典……" << endl;Dir_Init();Dict_Init();Dict_Write();printf("字典文件初始化完成。\n");//重新读取goto Dict_Read_start;}fp.read(reinterpret_cast<char*>(g_dict), sizeof(g_dict));if (!fp) {cerr << "读取文件时发生错误!" << endl;fp.close();return 0;}fp.close();printf("字典加载成功!\n");return 0;
}int Dict_Init() {g_dict[0].state = 1; //状态:0>未分配、1>有效、2>删除strcpy_s(g_dict[0].name, N, "noid");strcpy_s(g_dict[0].value, L, "1");strcpy_s(g_dict[0].comment, L, "下一个对象的编号");g_dict[1].state = 1;strcpy_s(g_dict[1].name, N, "ts");strcpy_s(g_dict[1].value, L, "1");strcpy_s(g_dict[1].comment, L, "TableSpace:存放表的结构数组的上限值");return 0;
}int Data_Init(vector<S_Table>& v_tables) {v_tables[0].name = "T0";v_tables[0].state = 2; //状态:0>未分配、1>新表、2>有数、3>删除、4>可复用v_tables[0].oid = 0;v_tables[0].rows = 3;v_tables[0].cols = 2;v_tables[0].record[0][0] = "H"; //数据&状态:"">未分配、H>字段名、A>可用、D>删除v_tables[0].record[0][1] = "TEL";v_tables[0].record[0][2] = "NAME";v_tables[0].record[1][0] = "A";v_tables[0].record[1][1] = "110";v_tables[0].record[1][2] = "Police";v_tables[0].record[2][0] = "A";v_tables[0].record[2][1] = "120";v_tables[0].record[2][2] = "Ambulance";v_tables[0].record[3][0] = "A";v_tables[0].record[3][1] = "119";v_tables[0].record[3][2] = "Fire";return 0;
}int Dir_Init() {if (_mkdir(DefaultPATH) == 0) {}else {}return 0;
}//end

※ 如果您觉得文章写的还不错, 别忘了在文末给作者点个赞哦 ~

20200426194203245.gif

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在idea中配置tomcat服务器,部署一个项目(下载教程加链接)

第一步&#xff1a;把Tomcat下载好 ww​​​​​​​Apache Tomcat - Welcome! 链接如上&#xff1a;进去后在左边找到Tomcat8点击进去后 找到图下内容 第二步&#xff1a; 打开这个文件点击bin进去 会出现一个黑色框框&#xff0c;也就是服务器 完成后就可以在浏览器输入…

掘根宝典之C++普通迭代器和反向迭代器详解

简介 迭代器是一种用于遍历容器元素的对象。它提供了一种统一的访问方式&#xff0c;使程序员可以对容器中的元素进行逐个访问和操作&#xff0c;而不需要了解容器的内部实现细节。 C标准库里每个容器都定义了迭代器&#xff0c;这迭代器的名字就叫容器迭代器 迭代器的作用类…

Yolo系列算法-理论部分-YOLOv1

0. 紧接上一篇目标检测算法的介绍 基于深度学习的目标检测算法概述-CSDN博客 本篇YOLO算法系列&#xff0c;参考优秀作者-AI菌&#xff0c;文章链接&#xff1a;YOLO系列算法精讲&#xff1a;从yolov1至yolov8的进阶之路&#xff08;2万字超全整理&#xff09;_yolov9-CSDN博…

deepin23beta中SQLite3数据库安装与使用

SQLite 是一个嵌入式 SQL 数据库引擎&#xff0c;它实现了一个自包含、无服务器、零配置、事务性 SQL 数据库引擎。 SQLite 的代码属于公共领域&#xff0c;因此可以免费用于任何商业或私人目的。 SQLite 是世界上部署最广泛的数据库&#xff0c;其应用程序数量之多&#xff0c…

HarmonyOS应用开发-Stage模型开发概述

基本概念 UI框架 HarmonyOS提供了一套UI开发框架&#xff0c;即方舟开发框架&#xff08;ArkUI框架&#xff09;。提供了应用UI开发所必需的能力&#xff1a;多种组件、布局计算、动画能力、UI交互、绘制。 方舟开发框架针对开发者提供了两种开发范式&#xff1a; 基于ArkTS…

STM32-位带操作及位带别名区

这里写自定义目录标题 一、位带操作的基本含义及作用二、以STM32为例三、位带别名区和位带区(寄存器地址位地址)的转换关系四、使用例程 一、位带操作的基本含义及作用 位带别名区的设计主要是为了**方便对位带区单个比特位进行读写操作**。在某些应用场景下&#xff0c;需要频…

Hive借助java反射解决User-agent编码乱码问题

一、需求背景 在截取到浏览器user-agent&#xff0c;并想保存入数据库中&#xff0c;经查询发现展示的为编码后的结果。 现需要经过url解码过程&#xff0c;将解码后的结果保存进数据库&#xff0c;那么有几种实现方式。 二、问题解决 1、百度&#xff1a;url在线解码工具 …

Java 与 Go:可变数组

可变数组&#xff08;也称为动态数组&#xff09;是一种可以在运行时动态增加或减少其大小的数据结构。由于其动态分配大小&#xff0c;灵活性增删改查&#xff0c;动态地管理内存&#xff08;在需要时动态分配内存空间&#xff0c;以适应数据结构的大小变化&#xff0c;而不会…

经典排序算法之基数排序详解|c++代码实现|简单易懂

引言 排序算法c实现系列第10弹&#xff08;最后一弹&#xff09;——基数排序。该系列文章主要讲解了十大经典排序算法&#xff0c;如最基础的冒泡排序、选择排序到借助堆数据结构实现的堆排序&#xff0c;其余所有算法的文章在本文最后都有链接&#xff0c;感兴趣的uu可以移步…

Java多线程实战-异步操作日志记录解决方案(AOP+注解+多线程)

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️本系列源码仓库&#xff1a;多线程并发编程学习的多个代码片段(github) &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正…

PHP异世界云商系统开源源码

系统更新与修复列表 1. 基于彩虹的二次开发 - 对彩虹系统进行了二次开发&#xff0c;增强了系统的功能和性能。2. 新增自定义输入框提示内容&#xff08;支持批量修改&#xff09; - 用户可以自定义输入框的提示内容&#xff0c;并支持批量修改&#xff0c;提升用户体验。3. 新…

18-结构体(初识)

18-1 概念 我们现在已经知道的数据类型&#xff1a; char short int long float double 但是当我们需要描述一个复杂对象时&#xff0c;这些数据类型单独拿出来不能满足&#xff0c;如&#xff1a; 人&#xff1a;名字年龄性别地址电话 书&#xff1a;书名作者出版社定价书…