private_sql.h文件(心虚,事实上离sql差了十万八千里)
#pragma once
#ifndef PRIVATE_SQL_H_H
#define PRIVATE_SQL_H_H
#include <string>//类成员,需要声明整个类
using namespace std;
class private_sql
{
public:
private_sql();
//新建表
int new_table(string tabname, string colname);
//新建行
int new_row(string tabname, string sqlstr);
//删除行
int delete_row(string tabname, string sqlstr);
//删除表
int delete_table(string tabname);
//更新数据
int updata_data(string tabname, string sqlstrset, string sqlstrwhere);
//新建列
int new_col(string tabname, string colname);
//删除列
int delete_col(string tabname, string colname);
typedef struct tab
{
int lock = 0;//对文本文件和结构体变量加锁,多线程间不要同时使用一个文本文件,不能同时使用一个结构体变量
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数//列名数与列名匹配字符数相等
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
}tab;
//查询三步
//查询表1
int select_table(tab * s, string tabname);
//显示读出的文件2
int show_tab(tab * s);
//清理结构体变量3
int clean_tab(tab * s);
//查询表,显示
int select_table_show(string tabname);
//调试工具
int set_sql();
};
#endif
private_sql.cpp文件(理想总是要有的,万一哪天实现了呢?)
#include "private_sql.h"
#include <iostream>
#include <fstream>
#include <regex>
#include <vector>
#include <WINSOCK2.H>
#include <stdio.h>
#include <string>
#include <stdlib.h>//用于随机生成字母
#include <time.h>//同上
#pragma comment(lib, "ws2_32.lib") 链接到WS2_32.lib
using namespace std;//不加这段命名空间,就会报错cout和endl未声
string vnameregex = "|zzljhfislefs|wjj*zzl|gdsergwazlefhsegslf|";//中间的*号作为数字位置识别标记
string vnameregextop = "|zzljhfislefs|wjj"; //列名匹配符前半
string vnameregexbot = "zzl|gdsergwazlefhsegslf|";
string rowregex = "|zzlesfeegdse|wjj*zzl|gdsergfdsezgtsdcnhu|";
string rowregextop = "|zzlesfeegdse|wjj"; //行名匹配符前半
string rowregexbot = "zzl|gdsergfdsezgtsdcnhu|";
string colregex = "|felzegidsfgieuze|wjj*zzl|geuponhuemrszun|";
string colregextop = "|felzegidsfgieuze|wjj"; //列匹配符前半
string colregexbot = "zzl|geuponhuemrszun|";
string VNAMESIZE = "[|][z][z][l][j][h][f][i][s][l][e][f][s][|][w][j][j][A-Z]*[0-9]*[z][z][l][|][g][d][s][e][r][g][w][a][z][l][e][f][h][s][e][g][s][l][f][|]";
string ROWSIZE = "[|][z][z][l][e][s][f][e][e][g][d][s][e][|][w][j][j][0-9]*[z][z][l][|][g][d][s][e][r][g][f][d][s][e][z][g][t][s][d][c][n][h][u][|]";
string COLSIZE = "[|][f][e][l][z][e][g][i][d][s][f][g][i][e][u][z][e][|][w][j][j][0-9]*[z][z][l][|][g][e][u][p][o][n][h][u][e][m][r][s][z][u][n][|]";
private_sql a;
typedef struct tab
{
int lock = 0;//对文本文件和结构体变量加锁,多线程间不要同时使用一个文本文件,不能同时使用一个结构体变量
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数//列名数与列名匹配字符数相等
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
}tab;
//一个自定义的头文件
private_sql::private_sql()
{
tab;
}
//注!重要事项,每次调用有全局自定义数组的函数后,都需要在下次调用前或者函数结尾时使用delete删除申请的空间;首次调用不需要删除空间
//id是一个特殊的列名,以id为列名的表,删除行的时候无法删除id
//另外,如修改id这样的操作是无效的,id不可更改
//以后可能修改新建表,使id自动增长从1开始
string strget(string strpath)
{
int i, str_length, c;
FILE *fi;
string str;
char path[1024];
sprintf(path, "%s", strpath.c_str());//string字符串赋值给字符数组需要在后面加.c_str()
//cout << path << endl;
fi = fopen(path, "r");
if (fi == NULL) {//rb读取为二进制
printf("该表不存在!");
return "false";
}
//____循环得到总的字符数_____________________________________________
i = 0;
while (1)
{
c = fgetc(fi);
if (EOF == c) { break; }
i++;
}
//cout << i << endl;
str_length = i;
char * strchar;//这是经典的数组长度定义
strchar = new char[str_length + 1];//通过new定数组长度(尽量往长了定义,不怕长就怕短)
rewind(fi);
i = 0;
while (1) {
c = fgetc(fi);//fgetc()读取函数,从文件中读取单个的字符,同时光标自动向后移一位
if (EOF == c) { strchar[i] = '\0'; break; }
//fputc(c,fo);//fputc()输出函数,把单个字符输出到文件中
strchar[i] = c;
//printf("%c", strchar[i]);
i++;
}
str = strchar;
//cout << str;
//Sleep(7000);
fclose(fi);
delete[] strchar;
return str;
}
//写入txt文档
int strgive(string strpath, string str)
{
int outsize, strlength, pathlength;
FILE *fo;
//cout << strpath << endl;
char *path, *ch;
outsize = strpath.length();
pathlength = outsize;
path = new char[outsize + 1];
outsize = str.length();
strlength = outsize;
ch = new char[outsize + 1];
strcpy(path, strpath.c_str());//C++中把string字符串转化为字符数组的代码
path[pathlength] = '\0';//不加'\0'会有意外错误
strcpy(ch, str.c_str());
ch[strlength] = '\0';
//
//sprintf(path, "%s", strpath.c_str());//string字符串赋值给字符数组需要在后面加.c_str()
//cout << path << endl;
//sprintf(ch, "%s", strcom.c_str());
fo = fopen(path, "w");
if (fo == NULL) {//rb读取为二进制
printf("该表不存在!");
return -1;
}
fputs(ch, fo);//向文本文档输入字符串,用fputs()
fclose(fo);
delete[] path;
delete[] ch;
return 1;
}
//正则匹配分割字符串,匹配后结果存入regexst.s[]数组,结果的个数存入regexst.idsize
struct MyStruct
{
int idsize;
string * s;
int idtize;
string * t;
};
MyStruct regexst;
int regex_stold(string str, string strreg)
{//返回-1表示被匹配字符串为空,返回-2匹配正则表达式为空,返回-10没有匹配的项目
regex reg(strreg);//加载正则匹配的公式
int i = 0;
int j = 0;
for (sregex_token_iterator it(str.begin(), str.end(), reg, -1), end; it != end; it++, i++) {
if (it->str() != "") {//因为有可能前面第一个就是匹配字符串,或者中间有连续而无意义的匹配字符
j++;
}
}
//cout << "j:" << j << endl;
regexst.idsize = j;
regexst.s = new string[i];
i = 0;
j = 0;
for (sregex_token_iterator it(str.begin(), str.end(), reg, -1), end; it != end; it++, i++) {
if (it->str() != "") {
regexst.s[j] = it->str();
//cout << regexst.s[j] << endl;
j++;
}
}
//记数字符串里匹配正则的个数,最后的个数i赋值给regexst.idtize,idtize是t的个数
smatch sm;
string strtoo = str;
i = 0;
while (regex_search(strtoo, sm, reg)) {
strtoo = sm.suffix().str();//每次循环,把剩余未匹配的字符串重新加入str字符串变量
i++;
}
regexst.idtize = i;
//cout << regexst.idtize << endl;
regexst.t = new string[i];
i = 0;
strtoo = str;
while (regex_search(strtoo, sm, reg)) {
for (int j = 0; j < sm.size(); ++j)
{
regexst.t[i] = sm[j];
//cout << regexst.t[i] << " ";
}
//cout << endl;
strtoo = sm.suffix().str();//每次循环,把剩余未匹配的字符串重新加入str字符串变量
i++;
}
return 1;
}
int regex_st(string str, string strreg)
{//返回-1表示被匹配字符串为空,返回-2匹配正则表达式为空,返回-10没有匹配的项目
regex reg(strreg);//加载正则匹配的公式
int i = 0;
int j = 0;
for (sregex_token_iterator it(str.begin(), str.end(), reg, -1), end; it != end; it++, i++) {
if (it->str() != "") {//因为有可能前面第一个就是匹配字符串,或者中间有连续而无意义的匹配字符
j++;
}
}
//cout << "j:" << j << endl;
regexst.idsize = j;
regexst.s = new string[i];
i = 0;
j = 0;
for (sregex_token_iterator it(str.begin(), str.end(), reg, -1), end; it != end; it++, i++) {
if (it->str() != "") {
regexst.s[j] = it->str();
//cout << regexst.s[j] << endl;
j++;
}
}
//记数字符串里匹配正则的个数,最后的个数i赋值给regexst.idtize,idtize是t的个数
smatch sm;
string strtoo = str;
i = 0;
while (regex_search(strtoo, sm, reg)) {
strtoo = sm.suffix().str();//每次循环,把剩余未匹配的字符串重新加入str字符串变量
i++;
}
regexst.idtize = i;
//cout << regexst.idtize << endl;
regexst.t = new string[i];
i = 0;
strtoo = str;
while (regex_search(strtoo, sm, reg)) {
for (int j = 0; j < sm.size(); ++j)
{
regexst.t[i] = sm[j];
//cout << regexst.t[i] << " ";
}
//cout << endl;
strtoo = sm.suffix().str();//每次循环,把剩余未匹配的字符串重新加入str字符串变量
i++;
}
return 1;
}
void delete_new_regex_st()
{
delete[] regexst.s;
delete[] regexst.t;
}
//分割字符串,分别存入数组,完成整表查询的功能
struct MySql_Sel {
//真正开始写功能实现,目标,匹配行标,匹配列标
//因为考虑到需要对空值作标记,想了想还是通过一串匹配字符完成,虽然会很占空间
//数据极其脆弱,不可以有换行,数值的字符间可以有空格,数值前后不可以有空格
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
};
MySql_Sel mysqlsel;
int mysql_sel(string tabname)
{
/*string tabname
列名:VNAMESIZE
行号:ROWSIZE
列号:COLSIZE
*/
int i = 0;//i和j是用于循环的时候记次的
int j = 0;
string str, strtoo, strtootoo;//保存原始字符串和初次加工去除列名列标的字符串
string strrow, strrowreg, strdatatype;//循环时,临时存放行字符串和和行字符串的匹配码;存放未匹配含数据类型的字符串
string stra, strb;
stra = "db\\" + tabname;
strb = stra + ".txt";
str = strget(strb);//调用自定义函数,获取txt文档内容,存为string字符串
if (str == "false") return -1;
//str = strget("db\\1.txt");
/*处理列名*/
regex_st(str, VNAMESIZE);//调用正则匹配的自定义函数,处理列名
//列名列数会比实际列名列数多一位,最后一位列名是匹配后余剩的字符串,将赋值给strtoo,再删除掉
mysqlsel.vregexsize = regexst.idtize;//把匹配到的列数赋值给列名的匹配字符数
mysqlsel.vnamesize = regexst.idtize;//把匹配到的列数赋值给列名数
mysqlsel.smcolsize = regexst.idtize - 1;//列数是列匹配符数减一
mysqlsel.vregex = new string[mysqlsel.vregexsize];//new动态分配数组大小,这是存放列名匹配码的数组
mysqlsel.vname = new string[mysqlsel.vregexsize];//new动态分配数组大小,这是存放列名的数组
mysqlsel.vdatatype = new string[mysqlsel.vregexsize];
i = 0;
while (1)
{
if (i == regexst.idtize) break;
mysqlsel.vregex[i] = regexst.t[i];//循环,把正则匹配到的字符一一存入数组(列名和列名匹配码)
mysqlsel.vname[i] = regexst.s[i];
//cout << "匹配到的列名匹配符:"<< mysqlsel.vregex[i] << endl;
//cout <<"匹配到的列名:" << mysqlsel.vname[i] << endl;
i++;
}
//cout << "mysqlsel.vname[mysqlsel.vnamesize-2]" << mysqlsel.vname[mysqlsel.vnamesize - 2] << endl;
//cout << "mysqlsel.vname[mysqlsel.vnamesize - 1]" << mysqlsel.vname[mysqlsel.vnamesize - 1] << endl;
strtoo = mysqlsel.vname[mysqlsel.vnamesize - 1];//把第一次匹配裁切的字符余下部分加入strtoo
mysqlsel.vname[mysqlsel.vnamesize - 1] = "";//把列名最后一位清空
//cout << strtoo << endl;
//cout << "一次匹配裁切的字符:" << strtoo << endl;
//打补丁,处理数据类型
i = 0;
strdatatype = "";
while (1)
{ //一套循环,把所有列名匹配码全拼接到strdatatype,作为预处理的数据
if (i == mysqlsel.vregexsize) break;
strdatatype += mysqlsel.vregex[i];
i++;
}
//cout << strdatatype << endl;
delete[] regexst.s;
delete[] regexst.t;
//if(regex_st(strdatatype, "[A-Z]+")<0)return -3;
regex_st(strdatatype, "[A-Z]+");
if (regexst.idtize != 0) {
i = 0;
while (1)
{
if (i == regexst.idtize) break;
mysqlsel.vdatatype[i] = regexst.t[i];
//cout << i << ":" << mysqlsel.vdatatype[i] << endl;
i++;
}
}
if (strtoo == "") {}
else {
/*处理行*/
string * prowregex;//临时的行匹配符存放位置
string * prow;//临时的行数据存放位置
string * pcolregex;//临时的列匹配符存放位置
string * pcol;//临时的列数据存放位置
//关闭正则的数组空间//为免内存泄漏,及各种因为不及时删除内存空间引起的报错,故每次调用函数前都需要运行相应的释放空间代码
delete[] regexst.s;
delete[] regexst.t;
regex_st(strtoo, ROWSIZE);//正则匹配,匹配行
if (regexst.idtize == 0) {}
else {
mysqlsel.smrowsize = regexst.idsize;//这是行数
prowregex = new string[mysqlsel.smrowsize];//new自定义数组大小,不用多说了
prow = new string[mysqlsel.smrowsize];
pcolregex = new string[mysqlsel.vnamesize - 1];//这四个都是临时存放数据的数组,这个函数里用完之后delete[] prowregex;删除
pcol = new string[mysqlsel.vnamesize - 1];
mysqlsel.srow = new string[mysqlsel.smrowsize];//存放行匹配码的一维数组
mysqlsel.scol = new string*[mysqlsel.smrowsize];//存放列匹配码的二维数组,行*列才是列匹配码的数量
mysqlsel.sm = new string*[mysqlsel.smrowsize];//最终结果,这里存放的是真正的数据,行数*列数
for (i = 0; i < mysqlsel.smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
mysqlsel.scol[i] = new string[mysqlsel.vnamesize - 1];//同样,把行号数赋值给列匹配码数组的每个维
mysqlsel.sm[i] = new string[mysqlsel.vnamesize - 1];//把行号数赋值给每个维
}
i = 0;
while (1)
{
if (i == mysqlsel.smrowsize) break;
prowregex[i] = regexst.t[i];//把每一行的匹配码字符串存入临时匹配码数组
prow[i] = regexst.s[i];//把每一行的待处理字符串存入临时行字符串数组
i++;
}
i = 0;
while (1)
{
if (i == mysqlsel.smrowsize) break;
strrowreg = prowregex[i];//把行匹配码存入strrowreg字符串变量,其实这一步有点多此一举,但是任性一把,懒得改了
mysqlsel.srow[i] = strrowreg;//存入行匹配字符串
strrow = prow[i];//同样,把待处理的每行字符串存入,strrow字符串变量
//cout << strrow << endl;
if (strrow != "") {
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(strrow, COLSIZE);//循环里调用正则匹配函数,这就是前面为什么要把正则匹配后的结果->未完
//->赶紧赋值给其他变量的原因,它会被覆盖掉
//cout << mysqlsel.vnamesize-1 << endl;
j = 0;//循环里面给j每次循环赋值,不能放外面否则要报错
while (1)
{
if (j == (mysqlsel.vnamesize - 1)) break;
//cout << regexst.s[j] << " ";
mysqlsel.scol[i][j] = regexst.t[j];//把正则匹配的列匹配码一一赋值给scol二维数组
mysqlsel.sm[i][j] = regexst.s[j];//把正则匹配到的数值一一赋值给sm二维数组
j++;
}
}
//cout << endl;
i++;
}
//cout << j<< endl;
//mysqlsel.smcolsize = j;
//显示验证是否完成数据的传递//这是一个用来测试用的循环,懒得删留着就留着吧
i = 0;
while (1)
{
if (i == mysqlsel.smrowsize) break;
//cout << mysqlsel.srow[i] << "===";
j = 0;
while (1)
{
if (j == (mysqlsel.vnamesize - 1)) break;
//cout << mysqlsel.scol[i][j]<< " |---| ";
//cout << mysqlsel.sm[i][j] << " |---| ";//
j++;
}
//cout << endl;
i++;
}
delete[] prowregex;
delete[] prow;
delete[] pcolregex;
delete[] pcol;
}
}
//删除正则匹配申请的空间
delete[] regexst.s;
delete[] regexst.t;
return 1;
}
void delete_new_sel()
{
//关闭查询的数组
delete[] mysqlsel.vregex;
delete[] mysqlsel.vdatatype;
delete[] mysqlsel.vname;
delete[] mysqlsel.srow;
//-----
int i;
for (i = 0; i < mysqlsel.smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
delete[] mysqlsel.scol[i];//把二维数组里的空间一一销毁
delete[] mysqlsel.sm[i];
}
delete[] mysqlsel.scol;
delete[] mysqlsel.sm;
}
//毫无意义的测试函数,无视即可
void srun()
{
//一个没什么大用的测试函数,测试数据传输成功不成功
cout << "srun对mysqlsel的测试:" << endl;
cout << "列名匹配符数量:" << mysqlsel.vregexsize << endl;
cout << "列名数量:" << mysqlsel.vnamesize << endl;
cout << "行数:" << mysqlsel.smrowsize << endl;
cout << "列数:" << mysqlsel.smcolsize << endl;
int j, i = 0;
while (1)
{
if (i == mysqlsel.vregexsize) break;
cout << "列名匹配符" << i << ":" << mysqlsel.vregex[i] << " ";
cout << "列名" << i << ":" << mysqlsel.vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == mysqlsel.smcolsize)break;
cout << "数据类型" << i << ":" << mysqlsel.vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == mysqlsel.smrowsize) break;
cout << "行匹配符" << i << ":" << mysqlsel.srow[i] << endl;
j = 0;
while (1)
{
if (j == (mysqlsel.vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << mysqlsel.scol[i][j] << " ";
cout << "正文数据" << i << ":" << mysqlsel.sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
/*增删改
分解开来,可以细分成几个函数,然后统一到一起再做成一个总函数
第一个函数
新建表(其实就是新建txt文件),新建表的时候,新建一个指定名字的新txt文档,位于根目录下db文件夹内
该表内,首次创建设置列名和列名匹配符,匹配符中间加数字从0开始
第二个函数
新建行,读取整个表,为了避免一些莫名其妙的错误没有组合数组,直接把读取出来的字符串拿来用,通过循环覆盖输入表内(一种简单粗暴的笨办法)
第三个函数
删除某行数据,读取整个表,把其中一行抽取出来全部注为NULL空值(不一定是NULL也可以是其他不易冲突的字符串),然后重新覆盖回文件,注不修改匹配码(假装删掉了,其实只是删掉了数值)
第四个函数
删除某个数值,更简单,读取整个表,把其中一个数值改成NULL空值,重新覆盖回去
第五个函数
修改一个数值,读取整个表,根据条件,找到对应数值然后修改它,再覆盖回去
第六个函数(感觉可以和第五个合并)
修改多个数值
注:有必要做个小函数,实现查询某个列名对应第几列的功能,或者根据条件,单条数值这个以后细化
万一读取一个表的时候,要读取另一个表,所以麻烦点,每次读取数据后,把数据转移到另一个临时数组(不知道结构体变量可不可以互相赋值)
*/
//以下是正式的函数
//新建表
int private_sql::new_table(string tabname, string colname)
{
int i, j;
int size;
char si[50];
string *strregid, *colstr, *datatype, strcom;
string strpath, strcolname;
string regexstr, stra, strb, strc, strd;
//准备地址
strpath = "db\\" + tabname;
strpath = strpath + ".txt";
///
//这里判断要新建的表是否存在
int outsize, pathlength;
char *path;
outsize = strpath.length();//strb是本自定义函数的表地址
pathlength = outsize;
path = new char[outsize + 1];
strcpy(path, strpath.c_str());//C++中把string字符串转化为字符数组的代码
path[pathlength] = '\0';
ifstream fin(path);
if (fin)
{
std::cout << "文件已存在!" << endl;
fin.close();
return -1;
}
///
//delete[] regexst.s;
//delete[] regexst.t;
//放弃数据类型的想法,统一CHAR,自动填充CHAR
strcolname = "";
regex_st(colname, "[ ]+");
j = regexst.idsize;
i = 0;
while (1)
{
if (i == j) break;
strcolname += "CHAR";
strcolname += " ";
strcolname += regexst.s[i];
strcolname += " ";
i++;
}
cout << strcolname << endl;
///
delete[] regexst.s;
delete[] regexst.t;
regex_st(strcolname, "[ ]+");
size = regexst.idsize / 2;
//cout << size << endl;
strregid = new string[size + 1];
colstr = new string[size];
datatype = new string[size];
i = 0;
while (1)
{
if (i == size) break;
colstr[i] = regexst.s[i * 2 + 1];
datatype[i] = regexst.s[i * 2];
i++;
}
//准备要输入的匹配字符串,切割组装
regexstr = "[\*]";
delete[] regexst.s;
delete[] regexst.t;
regex_st(vnameregex, regexstr);
stra = regexst.s[0];
strb = regexst.s[1];
//cout << regexst.s[0] << endl;
//cout << regexst.s[1] << endl;
//cout << regexst.t[0] << endl;
i = 0;
strcom = "";
while (1) {
if (i == (size + 1)) break;
//这里处理列匹配字符
sprintf(si, "%d", i);
strc = si;
if (i < size) {
strd = stra + datatype[i];
strc = strd + strc;
}
else {
strc = stra + strc;
}
strc = strc + strb;
//cout << strc << endl;
strregid[i] = strc;
strcom = strcom + strregid[i];
//cout << strregid[i] << endl;
if (i == size) {}
else {
//这里处理列名
strcom = strcom + colstr[i];
}
//fputc(c, fo);//fputc()输出函数,把单个字符输出到文件中
i++;
}
//cout << strpath << endl;
//cout << strcom << endl;
/*//本想在这里加一个补丁,初始化的时候默认添加第一行,但是想到会影响后面的数据
i = 0;
while (1)
{
if (i == size) break;
strcom+=colregextop
i++;
}
*/
//strgive(strpath,strcom);
//代替strgive的补丁
if (1)
{
int outsize, strlength, pathlength;
FILE *fo;
//cout << strpath << endl;
char *path, *ch;
outsize = strpath.length();
pathlength = outsize;
path = new char[outsize + 1];
outsize = strcom.length();
strlength = outsize;
ch = new char[outsize + 1];
strcpy(path, strpath.c_str());//C++中把string字符串转化为字符数组的代码
path[pathlength] = '\0';
strcpy(ch, strcom.c_str());
ch[strlength] = '\0';
//
//sprintf(path, "%s", strpath.c_str());//string字符串赋值给字符数组需要在后面加.c_str()
//cout << path << endl;
//sprintf(ch, "%s", strcom.c_str());
fo = fopen(path, "w");
if (fo == NULL) {//rb读取为二进制
printf("该表不存在!");
}
fputs(ch, fo);//向文本文档输入字符串,用fputs()
fclose(fo);
delete[] path;
delete[] ch;
}
//delete[] colname;
delete[] strregid;
delete[] regexst.s;
delete[] regexst.t;
return 1;
}
//新建行
int private_sql::new_row(string tabname, string sqlstr)
{
//一行数据由,行匹配码(当前行+1),列匹配码,每列一个与列标保持一致,数据组成(没有数据的以NULL表示)
int colid;
///
//这里判断要新建列的表是否存在
int coutsize, cpathlength;
FILE *cfi;
string strpath;
char *cpath;
strpath = "db\\" + tabname;
strpath = strpath + ".txt";
coutsize = strpath.length();
cpathlength = coutsize;
cpath = new char[coutsize + 1];
strcpy(cpath, strpath.c_str());//C++中把string字符串转化为字符数组的代码
cpath[cpathlength] = '\0';
cfi = fopen(cpath, "r");
if (cfi == NULL) {//rb读取为二进制
cout << "该表不存在!" << endl;
return -1;
}
fclose(cfi);
delete[] cpath;
///
int i, j, z;
string *newdataname, *newsm;
string newstrdatatype, newstrsm, strcom, stra, strb;
i = mysql_sel(tabname);
//cout << "mysql_sel()的返回值:"<<i <<endl ;
i = 0;
while (1)
{
if (i == mysqlsel.vnamesize) break;
if (mysqlsel.vname[i] == "id") {
colid = i;
}
i++;
}
regex_st(sqlstr, "[ ]+");
//cout << regexst.idsize << endl;
//if ((regexst.idsize / 2) != mysqlsel.smcolsize) return -1;//判断输入的字符数量是否符合规则
if (regexst.idsize <= 1) return -1;
if (regexst.idsize % 2 == 0) {}
else return -2;
newdataname = new string[mysqlsel.smcolsize + 1];
newsm = new string[mysqlsel.smcolsize + 1];
//cout << "列数:" << mysqlsel.smcolsize << endl;
//校验输入的列名数量是否有超
if ((regexst.idsize / 2) > mysqlsel.smcolsize) return -2;
//校验输入的列名是否有重复
i = 0;
z = 0;
while (1)
{
if (i == (regexst.idsize / 2)) break;
j = 0;
while (1)
{
if (j == (regexst.idsize / 2)) break;
if (regexst.s[i] == regexst.s[j])
{
z++;
}
j++;
}
i++;
}
if (z != (regexst.idsize / 2)) return -3;
//校验匹配的名字数量与输入的列名是否相同
i = 0;
z = 0;
while (1)
{
if (i == (mysqlsel.vregexsize - 1)) break;
j = 0;
//cout << "读取到的txt原始列名:" << mysqlsel.vname[i] << endl;
//cout << "读取到的txt原始列名匹配符:" << mysqlsel.vregex[i] << endl;
while (1)
{
if (j == (regexst.idsize / 2)) break;
if (regexst.s[j] == mysqlsel.vname[i]) {
//cout << "匹配的列名:" << regexst.s[j] << endl;
z++;
}
j++;
}
i++;
}
//cout <<"z:"<< z << endl;
if (z != (regexst.idsize / 2)) return -4;
//这里把数据存入准备数组,作为添加进strcom前的预处理数据
i = 0;
while (1)
{
if (i == (mysqlsel.vregexsize - 1)) break;
j = 0;
while (1)
{
if (j == (regexst.idsize / 2))break;
//cout <<" mysqlsel.vname[i]:"<< mysqlsel.vname[i] << endl;
//cout << "regexst.s[j]:" << regexst.s[j] << endl;
if (mysqlsel.vname[i] == regexst.s[j])
{
newdataname[i] = regexst.s[j];
newsm[i] = regexst.s[j + (regexst.idsize / 2)];
break;
}
else {
newdataname[i] = mysqlsel.vname[i];
newsm[i] = "NULL";
}
j++;
}
i++;
}
newsm[colid] = to_string(mysqlsel.smrowsize + 1);
stra = "db\\" + tabname;
strb = stra + ".txt";
strcom = strget(strb);
i = 0;
//先把当前要添加的那一行的行匹配符添加进去
strcom += rowregextop;
strcom += to_string(mysqlsel.smrowsize);
strcom += rowregexbot;
//cout << "加入新一行行匹配码的strcom:" << strcom << endl;
delete_new_sel();
//cout << "测试数字转string字符串:" << to_string(j) <<endl;
while (1)
{
if (i == mysqlsel.smcolsize) break;
strcom += colregextop;
strcom += to_string(i);
strcom += colregexbot;
strcom += newsm[i];//遇到了BUG,已经改过试试看
i++;
}
//cout << "输入新一行之后的strcom:" << strcom << endl;
if (strgive(strb, strcom) < 0) return -5;
delete[] regexst.s;
delete[] regexst.t;
delete[] newdataname;
delete[] newsm;
return 1;
}
//删除行
int private_sql::delete_row(string tabname, string sqlstr)
{
int k = 0, j = 0, i = 0, z = 0;
//-----------------------------------------------------------
string *wvname, *wdata;
int ci;//需要查询的次数,也是条件数
//-----------------------------------------------------------
//***********************************************************
int *smdelete;
int id, tf;
string strid, strcom, strx, stry;
//***********************************************************
/
string str, strtoo, strtootoo;//保存原始字符串和初次加工去除列名列标的字符串
string strrow, strrowreg, strdatatype;//循环时,临时存放行字符串和和行字符串的匹配码;存放未匹配含数据类型的字符串
string stra, strb;//处理地址
/
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数//列名数与列名匹配字符数相等
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
/
/
//还是重新改一遍查询代码吧,这个函数和其他函数一起循环的时候会出内存错误
/*string tabname
列名:VNAMESIZE
行号:ROWSIZE
列号:COLSIZE
*/
stra = "db\\" + tabname;
strb = stra + ".txt";
str = strget(strb);//调用自定义函数,获取txt文档内容,存为string字符串
if (str == "false") return -1;
//str = strget("db\\1.txt");
/
/*处理列名*//*正则匹配列名匹配符*/
regex_st(str, VNAMESIZE);//调用正则匹配的自定义函数,处理列名
/
//列名列数会比实际列名列数多一位,最后一位列名是匹配后余剩的字符串,将赋值给strtoo,再删除掉
vregexsize = regexst.idtize;//把匹配到的列数赋值给列名的匹配字符数
vnamesize = regexst.idtize;//把匹配到的列数赋值给列名数
smcolsize = regexst.idtize - 1;//列数是列匹配符数减一
vregex = new string[vregexsize];//new动态分配数组大小,这是存放列名匹配码的数组
vname = new string[vregexsize];//new动态分配数组大小,这是存放列名的数组
vdatatype = new string[vregexsize];
/
//处理列名和列名匹配符
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vregex[i] = regexst.t[i];//循环,把正则匹配到的字符一一存入数组(列名和列名匹配码)
vname[i] = regexst.s[i];
i++;
}
//把第一次匹配裁切的字符余下部分加入strtoo
strtoo = vname[vnamesize - 1];
vname[vnamesize - 1] = "";//把列名最后一位清空
/
//处理数据类型
i = 0;
strdatatype = "";
while (1)
{ //一套循环,把所有列名匹配码全拼接到strdatatype,作为预处理的数据
if (i == vregexsize) break;
strdatatype += vregex[i];
i++;
}
//删除内存空间
delete[] regexst.s;
delete[] regexst.t;
//正则匹配大写的数据类型
regex_st(strdatatype, "[A-Z]+");
if (regexst.idtize != 0) {
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vdatatype[i] = regexst.t[i];
i++;
}
}
/
//处理接下来的行与列
/*处理行*/
string * prowregex;//临时的行匹配符存放位置
string * prow;//临时的行数据存放位置
string * pcolregex;//临时的列匹配符存放位置
string * pcol;//临时的列数据存放位置
//关闭正则的数组空间//为免内存泄漏,及各种因为不及时删除内存空间引起的报错,故每次调用函数前都需要运行相应的释放空间代码
delete[] regexst.s;
delete[] regexst.t;
regex_st(strtoo, ROWSIZE);//正则匹配,匹配行
/
//得到行数后,给剩下的数组申请空间
smrowsize = regexst.idsize;//这是行数
//给临时数组申请内存空间
prowregex = new string[smrowsize];//new自定义数组大小,不用多说了
prow = new string[smrowsize];
pcolregex = new string[vnamesize - 1];//这四个都是临时存放数据的数组,这个函数里用完之后delete[] prowregex;删除
pcol = new string[vnamesize - 1];
//给正式的数组申请内存空间
srow = new string[smrowsize];//存放行匹配码的一维数组
scol = new string*[smrowsize];//存放列匹配码的二维数组,行*列才是列匹配码的数量
sm = new string*[smrowsize];//最终结果,这里存放的是真正的数据,行数*列数
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
scol[i] = new string[vnamesize - 1];//同样,把行号数赋值给列匹配码数组的每个维
sm[i] = new string[vnamesize - 1];//把行号数赋值给每个维
}
/
//符合strtoo不为空,才执行下面{}内的代码
if (strtoo == "") {}
else {
/
//符合行数不等于0,才执行下面{}内的代码
if (smrowsize == 0) {}
else {
/
//给临时数组的行匹配符行数据赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
prowregex[i] = regexst.t[i];//把每一行的匹配码字符串存入临时匹配码数组
prow[i] = regexst.s[i];//把每一行的待处理字符串存入临时行字符串数组
i++;
}
/
//给正式数组的行匹配符数组、列匹配符数组、sm数据数组赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
strrowreg = prowregex[i];//把行匹配码存入strrowreg字符串变量,其实这一步有点多此一举,但是任性一把,懒得改了
srow[i] = strrowreg;//存入行匹配字符串
strrow = prow[i];//同样,把待处理的每行字符串存入,strrow字符串变量
//cout << strrow << endl;
if (strrow != "") {
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(strrow, COLSIZE);//循环里调用正则匹配函数,这就是前面为什么要把正则匹配后的结果->未完
//->赶紧赋值给其他变量的原因,它会被覆盖掉
//cout << mysqlsel.vnamesize-1 << endl;
j = 0;//循环里面给j每次循环赋值,不能放外面否则要报错
while (1)
{
if (j == (vnamesize - 1)) break;
//cout << regexst.s[j] << " ";
scol[i][j] = regexst.t[j];//把正则匹配的列匹配码一一赋值给scol二维数组
sm[i][j] = regexst.s[j];//把正则匹配到的数值一一赋值给sm二维数组
j++;
}
}
//cout << endl;
i++;
}
}
}
/
//删除临时数组的内存空间
delete[] prowregex;
delete[] prow;
delete[] pcolregex;
delete[] pcol;
/
/
/
//循环测试
if (0) {
cout << "delete_row的赋值测试:" << endl;
cout << "列名匹配符数量:" << vregexsize << endl;
cout << "列名数量:" << vnamesize << endl;
cout << "行数:" << smrowsize << endl;
cout << "列数:" << smcolsize << endl;
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
cout << "列名匹配符" << i << ":" << vregex[i] << " ";
cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == smcolsize)break;
cout << "数据类型" << i << ":" << vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == smrowsize) break;
cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << scol[i][j] << " ";
cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
/
//-----------------------------------------------------------
//以下是分析sqlstr的命令,把数值分类存入数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(sqlstr, "[ ]+");
//-----------------------------------------------------------
if (1)
{
//校验输入的列名数量是否有超
if ((regexst.idsize / 2) > smcolsize) return -2;
//校验输入的列名是否有重复
i = 0;
z = 0;
while (1)
{
if (i == (regexst.idsize / 2)) break;
j = 0;
while (1)
{
if (j == (regexst.idsize / 2)) break;
if (regexst.s[i] == regexst.s[j])
{
z++;
}
j++;
}
i++;
}
if (z != (regexst.idsize / 2)) return -3;
//校验匹配的名字数量与输入的列名是否相同
i = 0;
z = 0;
while (1)
{
if (i == (vregexsize - 1)) break;
j = 0;
while (1)
{
if (j == (regexst.idsize / 2)) break;
if (regexst.s[j] == vname[i]) {
z++;
}
j++;
}
i++;
}
if (z != (regexst.idsize / 2)) return -4;
}
//-----------------------------------------------------------
ci = regexst.idsize / 2;
wvname = new string[ci];
wdata = new string[ci];
i = 0;
while (1)
{
if (i == ci) break;
wvname[i] = regexst.s[i];
i++;
}
i = 0;
while (1)
{
if (i == ci) break;
wdata[i] = regexst.s[i + ci];
i++;
}
//-----------------------------------------------------------
//这是对上面一段代码的测试,看是否有误
//-----------------------------------------------------------
if (0)
{
i = 0;
while (1)
{
if (i == ci) break;
//cout << "条件里的列名输入数组:" << wvname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == ci) break;
//cout << "条件里的数值输入数组:" << wdata[i] << endl;
i++;
}
}
//-----------------------------------------------------------
//***********************************************************
//这是解决代码循环的逻辑部分
//***********************************************************
//先搞个存储delete删除标记的数组,大小与sm数组一样
//思路是,每当条件匹配,数组与sm对应的坐标数值+1
//最后数值与条件数ci相等的坐标,就是sm中要删除数据的坐标(也是行的坐标)
//***********************************************************
//向内存申请空间
smdelete = new int[smrowsize];
//***********************************************************
//初始化smdelete数组,赋值为0
i = 0;
while (1)
{
if (i == smrowsize) break;
smdelete[i] = 0;
i++;
}
//***********************************************************
//循环,符合条件就给smdelete数组+1
i = 0;
j = 0;
k = 0;
while (1)//循环次数为where条件数
{
if (i == ci)break;
//cout <<"条件的列名:" <<wvname[i]<<endl;
//cout << "条件的数值:" << wdata[i] << endl;
j = 0;
while (1)//循环行
{
if (j == smrowsize) break;
k = 0;
while (1)//循环列
{
if (k == smcolsize) break;
if (vname[k] == wvname[i]) //where条件的列名与vname列名相同则执行{}内代码
{
if (sm[j][k] == wdata[i])//where条件的数值与sm数组的数值相等则执行{}内代码
{
smdelete[j]++;
}
}
k++;
}
j++;
}
i++;
}
//***********************************************************
//找到id对应的列,该列对应的i值存入id
i = 0;
while (1)
{
if (i == vnamesize) break;
if (vname[i] == "id")
{
id = i;
}
i++;
}
//***********************************************************
//把符合条件的行,注为NULL空值
//cout << "------------------------" << endl;
i = 0;
tf = 0;
while (1)//循环行
{
if (i == smrowsize) break;
j = 0;
while (1)//循环列
{
if (j == smcolsize) break;
//cout << smdelete[i] << endl;
if (smdelete[i] == ci) //满足smdelete数组数值等于ci的,执行{}内代码
{
//cout << "符合条件的:" << "行:" << i << "列" << j << endl;
k = 0;
while (1)//还是循环列,把这一行的列全删除,除id以外
{
if (k == smcolsize) break;
//cout <<"id对应的vname没起效:"<< vname[k] << endl;
strid = sm[i][id];//一个戏法暂时把值放在第三方变量
sm[i][j] = "NULL";
sm[i][id] = strid;//等注空为NULL之后,再把id的数值存回来
k++;
}
tf = 1;//假如有全部条件都符合的(不管是一条还是多条),就把tf的值改为1
}
j++;
}
i++;
}
//***********************************************************
//这是返回是否符合所有条件,如果有一个不满足的条件,就返回报错信息
if (tf == 0) return -5;
//***********************************************************
//测试数组值删除情况
if (0) {
cout << "delete_row的赋值测试:" << endl;
cout << "列名匹配符数量:" << vregexsize << endl;
cout << "列名数量:" << vnamesize << endl;
cout << "行数:" << smrowsize << endl;
cout << "列数:" << smcolsize << endl;
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
cout << "列名匹配符" << i << ":" << vregex[i] << " ";
cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == smcolsize)break;
cout << "数据类型" << i << ":" << vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == smrowsize) break;
cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << scol[i][j] << " ";
cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
//***********************************************************
//把修改后的数组组合成string字符串
strcom = "";
//首先组合列名匹配符和列名
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
strcom += vregex[i];
strcom += vname[i];
//cout << "列名匹配符" << i << ":" << vregex[i] << " ";
//cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
//然后组合行匹配符+列匹配符+正文数据
i = 0;
while (1)
{
if (i == smrowsize) break;
strcom += srow[i];
//cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
strcom += scol[i][j];
strcom += sm[i][j];
//cout << "列匹配符" << i << ":" << scol[i][j] << " ";
//cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
//cout << endl;
i++;
}
//cout <<"完成所有数据组合后的strcom:"<< strcom << endl;
//***********************************************************
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//这是一个完整一体的string字符串输入txt文档代码
//用于完成最后一步,把strcom输入对应的表
if (1)
{
int outsize, strlength, pathlength;
FILE *fo;
char *path, *ch;
outsize = strb.length();//strb是本自定义函数的表地址
pathlength = outsize;
path = new char[outsize + 1];
outsize = strcom.length();
strlength = outsize;
ch = new char[outsize + 1];
strcpy(path, strb.c_str());//C++中把string字符串转化为字符数组的代码
path[pathlength] = '\0';
strcpy(ch, strcom.c_str());
ch[strlength] = '\0';
//
//sprintf(path, "%s", strpath.c_str());//string字符串赋值给字符数组需要在后面加.c_str()
//cout << path << endl;
//sprintf(ch, "%s", strcom.c_str());
fo = fopen(path, "w");
if (fo == NULL) {//rb读取为二进制
printf("该表不存在!");
return -6;
}
fputs(ch, fo);//向文本文档输入字符串,用fputs()
fclose(fo);
delete[] path;
delete[] ch;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//***********************************************************
//删除申请的内存空间
delete[] smdelete;
//***********************************************************
/
//删除数组的内存空间
delete[] vregex;
delete[] vdatatype;
delete[] vname;
delete[] srow;
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
delete[] scol[i];//把二维数组里的空间一一销毁
delete[] sm[i];
}
delete[] scol;
delete[] sm;
/
//-----------------------------------------------------------
//删除申请的内存空间
delete[] wvname;
delete[] wdata;
//-----------------------------------------------------------
delete[] regexst.s;
delete[] regexst.t;
//-----------------------------------------------------------
return 1;
}
//删除表
int private_sql::delete_table(string tabname)
{
int i;
string strpath, stra, strb;
//----------------------------------------------------------------------------------
//准备地址
strpath = "db\\" + tabname;
strpath = strpath + ".txt";
//----------------------------------------------------------------------------------
//实现删除某个表的功能
//==================================================================================
//判断要删除的表是否存在
//这里判断要新建的表是否存在
int outsize, pathlength;
FILE *fo;
char *path;
outsize = strpath.length();//strb是本自定义函数的表地址
pathlength = outsize;
path = new char[outsize + 1];
strcpy(path, strpath.c_str());//C++中把string字符串转化为字符数组的代码
path[pathlength] = '\0';
fo = fopen(path, "r");
if (fo == NULL) {//rb读取为二进制
cout << "要删除的表不存在!" << endl;
return -1;
}
fclose(fo);//不关闭指针,删除操作是做不了的
//==================================================================================
//**********************************************************************************
if (remove(path) == 0)//C++中删除文件的函数
{
//cout << "删除成功!" << endl;
}
else
{
cout << "删除失败!" << endl;
return -2;
}
//**********************************************************************************
return 1;
}
//更新数据
int private_sql::updata_data(string tabname, string sqlstrset, string sqlstrwhere)
{
//和单纯删除不同,修改数据,除了有作为条件的字符串外,还有修改的部分字符串,为了方便操作,给它分成两个string字符串
int k = 0, j = 0, i = 0, z = 0;
//-----------------------------------------------------------
string *wvname, *wdata;
int ci;//需要查询的次数,也是条件数
//-----------------------------------------------------------
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
int ciset;
string *setvname, *setdata;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//***********************************************************
int *smdelete;
int id;
string strid, strcom;
//***********************************************************
/
string str, strtoo, strtootoo;//保存原始字符串和初次加工去除列名列标的字符串
string strrow, strrowreg, strdatatype;//循环时,临时存放行字符串和和行字符串的匹配码;存放未匹配含数据类型的字符串
string stra, strb;//处理地址
/
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数//列名数与列名匹配字符数相等
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
/
/
//还是重新改一遍查询代码吧,这个函数和其他函数一起循环的时候会出内存错误
/*string tabname
列名:VNAMESIZE
行号:ROWSIZE
列号:COLSIZE
*/
stra = "db\\" + tabname;
strb = stra + ".txt";
str = strget(strb);//调用自定义函数,获取txt文档内容,存为string字符串
if (str == "false") return -1;
//str = strget("db\\1.txt");
/
/*处理列名*//*正则匹配列名匹配符*/
regex_st(str, VNAMESIZE);//调用正则匹配的自定义函数,处理列名
/
//列名列数会比实际列名列数多一位,最后一位列名是匹配后余剩的字符串,将赋值给strtoo,再删除掉
vregexsize = regexst.idtize;//把匹配到的列数赋值给列名的匹配字符数
vnamesize = regexst.idtize;//把匹配到的列数赋值给列名数
smcolsize = regexst.idtize - 1;//列数是列匹配符数减一
vregex = new string[vregexsize];//new动态分配数组大小,这是存放列名匹配码的数组
vname = new string[vregexsize];//new动态分配数组大小,这是存放列名的数组
vdatatype = new string[vregexsize];
/
//处理列名和列名匹配符
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vregex[i] = regexst.t[i];//循环,把正则匹配到的字符一一存入数组(列名和列名匹配码)
vname[i] = regexst.s[i];
i++;
}
//把第一次匹配裁切的字符余下部分加入strtoo
strtoo = vname[vnamesize - 1];
vname[vnamesize - 1] = "";//把列名最后一位清空
/
//处理数据类型
i = 0;
strdatatype = "";
while (1)
{ //一套循环,把所有列名匹配码全拼接到strdatatype,作为预处理的数据
if (i == vregexsize) break;
strdatatype += vregex[i];
i++;
}
//删除内存空间
delete[] regexst.s;
delete[] regexst.t;
//正则匹配大写的数据类型
regex_st(strdatatype, "[A-Z]+");
if (regexst.idtize != 0) {
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vdatatype[i] = regexst.t[i];
i++;
}
}
/
//处理接下来的行与列
/*处理行*/
string * prowregex;//临时的行匹配符存放位置
string * prow;//临时的行数据存放位置
string * pcolregex;//临时的列匹配符存放位置
string * pcol;//临时的列数据存放位置
//关闭正则的数组空间//为免内存泄漏,及各种因为不及时删除内存空间引起的报错,故每次调用函数前都需要运行相应的释放空间代码
delete[] regexst.s;
delete[] regexst.t;
regex_st(strtoo, ROWSIZE);//正则匹配,匹配行
/
//得到行数后,给剩下的数组申请空间
smrowsize = regexst.idsize;//这是行数
//给临时数组申请内存空间
prowregex = new string[smrowsize];//new自定义数组大小,不用多说了
prow = new string[smrowsize];
pcolregex = new string[vnamesize - 1];//这四个都是临时存放数据的数组,这个函数里用完之后delete[] prowregex;删除
pcol = new string[vnamesize - 1];
//给正式的数组申请内存空间
srow = new string[smrowsize];//存放行匹配码的一维数组
scol = new string*[smrowsize];//存放列匹配码的二维数组,行*列才是列匹配码的数量
sm = new string*[smrowsize];//最终结果,这里存放的是真正的数据,行数*列数
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
scol[i] = new string[vnamesize - 1];//同样,把行号数赋值给列匹配码数组的每个维
sm[i] = new string[vnamesize - 1];//把行号数赋值给每个维
}
/
//符合strtoo不为空,才执行下面{}内的代码
if (strtoo == "") {}
else {
/
//符合行数不等于0,才执行下面{}内的代码
if (smrowsize == 0) {}
else {
/
//给临时数组的行匹配符行数据赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
prowregex[i] = regexst.t[i];//把每一行的匹配码字符串存入临时匹配码数组
prow[i] = regexst.s[i];//把每一行的待处理字符串存入临时行字符串数组
i++;
}
/
//给正式数组的行匹配符数组、列匹配符数组、sm数据数组赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
strrowreg = prowregex[i];//把行匹配码存入strrowreg字符串变量,其实这一步有点多此一举,但是任性一把,懒得改了
srow[i] = strrowreg;//存入行匹配字符串
strrow = prow[i];//同样,把待处理的每行字符串存入,strrow字符串变量
//cout << strrow << endl;
if (strrow != "") {
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(strrow, COLSIZE);//循环里调用正则匹配函数,这就是前面为什么要把正则匹配后的结果->未完
//->赶紧赋值给其他变量的原因,它会被覆盖掉
//cout << mysqlsel.vnamesize-1 << endl;
j = 0;//循环里面给j每次循环赋值,不能放外面否则要报错
while (1)
{
if (j == (vnamesize - 1)) break;
//cout << regexst.s[j] << " ";
scol[i][j] = regexst.t[j];//把正则匹配的列匹配码一一赋值给scol二维数组
sm[i][j] = regexst.s[j];//把正则匹配到的数值一一赋值给sm二维数组
j++;
}
}
//cout << endl;
i++;
}
}
/
//删除临时数组的内存空间
delete[] prowregex;
delete[] prow;
delete[] pcolregex;
delete[] pcol;
}
/
/
/
//循环测试
if (0) {
cout << "updata_data的赋值测试:" << endl;
cout << "列名匹配符数量:" << vregexsize << endl;
cout << "列名数量:" << vnamesize << endl;
cout << "行数:" << smrowsize << endl;
cout << "列数:" << smcolsize << endl;
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
cout << "列名匹配符" << i << ":" << vregex[i] << " ";
cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == smcolsize)break;
cout << "数据类型" << i << ":" << vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == smrowsize) break;
cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << scol[i][j] << " ";
cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
/
//-----------------------------------------------------------
//以下是分析sqlstrwhere的命令,把数值分类存入数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(sqlstrwhere, "[ ]+");
//-----------------------------------------------------------
if (1)
{
//校验输入的列名数量是否有超
if ((regexst.idsize / 2) > smcolsize) return -2;
//校验输入的列名是否有重复
i = 0;
z = 0;
while (1)
{
if (i == (regexst.idsize / 2)) break;
j = 0;
while (1)
{
if (j == (regexst.idsize / 2)) break;
if (regexst.s[i] == regexst.s[j])
{
z++;
}
j++;
}
i++;
}
if (z != (regexst.idsize / 2)) return -3;
//校验匹配的名字数量与输入的列名是否相同
i = 0;
z = 0;
while (1)
{
if (i == (vregexsize - 1)) break;
j = 0;
while (1)
{
if (j == (regexst.idsize / 2)) break;
if (regexst.s[j] == vname[i]) {
z++;
}
j++;
}
i++;
}
if (z != (regexst.idsize / 2)) return -4;
}
//-----------------------------------------------------------
ci = regexst.idsize / 2;
wvname = new string[ci];
wdata = new string[ci];
i = 0;
while (1)
{
if (i == ci) break;
wvname[i] = regexst.s[i];
i++;
}
i = 0;
while (1)
{
if (i == ci) break;
wdata[i] = regexst.s[i + ci];
i++;
}
//-----------------------------------------------------------
//这是对上面一段代码的测试,看是否有误
//-----------------------------------------------------------
if (0)
{
i = 0;
while (1)
{
if (i == ci) break;
//cout << "条件里的列名输入数组:" << wvname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == ci) break;
//cout << "条件里的数值输入数组:" << wdata[i] << endl;
i++;
}
}
//-----------------------------------------------------------
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//以下是分析sqlstrwhere的命令,把数值分类存入数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(sqlstrset, "[ ]+");
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
if (1)
{
//校验输入的列名数量是否有超
if ((regexst.idsize / 2) > smcolsize) return -2;
//校验输入的列名是否有重复
i = 0;
z = 0;
while (1)
{
if (i == (regexst.idsize / 2)) break;
j = 0;
while (1)
{
if (j == (regexst.idsize / 2)) break;
if (regexst.s[i] == regexst.s[j])
{
z++;
}
j++;
}
i++;
}
if (z != (regexst.idsize / 2)) return -3;
//校验匹配的名字数量与输入的列名是否相同
i = 0;
z = 0;
while (1)
{
if (i == (vregexsize - 1)) break;
j = 0;
while (1)
{
if (j == (regexst.idsize / 2)) break;
if (regexst.s[j] == vname[i]) {
z++;
}
j++;
}
i++;
}
if (z != (regexst.idsize / 2)) return -4;
}
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
ciset = regexst.idsize / 2;
setvname = new string[ciset];
setdata = new string[ciset];
i = 0;
while (1)
{
if (i == ciset) break;
setvname[i] = regexst.s[i];
i++;
}
i = 0;
while (1)
{
if (i == ciset) break;
setdata[i] = regexst.s[i + ciset];
i++;
}
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//这是对上面一段代码的测试,看是否有误
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
if (1)
{
i = 0;
while (1)
{
if (i == ciset) break;
//cout << "set里的列名输入数组:" << setvname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == ciset) break;
//cout << "set里的数值输入数组:" << setdata[i] << endl;
i++;
}
}
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//***********************************************************
//这是解决代码循环的逻辑部分
//***********************************************************
//先搞个存储delete删除标记的数组,大小与sm数组一样
//思路是,每当条件匹配,数组与sm对应的坐标数值+1
//最后数值与条件数ci相等的坐标,就是sm中要删除数据的坐标(也是行的坐标)
//***********************************************************
//向内存申请空间
smdelete = new int[smrowsize];
//***********************************************************
//初始化smdelete数组,赋值为0
i = 0;
while (1)
{
if (i == smrowsize) break;
smdelete[i] = 0;
i++;
}
//***********************************************************
//循环,符合条件就给smdelete数组+1
i = 0;
j = 0;
k = 0;
while (1)//循环次数为where条件数
{
if (i == ci)break;
//cout <<"条件的列名:" <<wvname[i]<<endl;
//cout << "条件的数值:" << wdata[i] << endl;
j = 0;
while (1)//循环行
{
if (j == smrowsize) break;
k = 0;
while (1)//循环列
{
if (k == smcolsize) break;
if (vname[k] == wvname[i]) //where条件的列名与vname列名相同则执行{}内代码
{
if (sm[j][k] == wdata[i])//where条件的数值与sm数组的数值相等则执行{}内代码
{
smdelete[j]++;
}
}
k++;
}
j++;
}
i++;
}
//***********************************************************
//找到id对应的列,该列对应的i值存入id
i = 0;
while (1)
{
if (i == vnamesize) break;
if (vname[i] == "id")
{
id = i;
}
i++;
}
//***********************************************************
//把符合条件的行,注为NULL空值
i = 0;
while (1)//循环行
{
if (i == smrowsize) break;
if (smdelete[i] == ci)
{
strid = sm[i][id];
j = 0;
while (1)//循环列
{
if (j == smcolsize) break;
k = 0;
while (1)//循环set的ciset次数
{
if (k == ciset) break;
if (vname[j] == setvname[k])
{
sm[i][j] = setdata[k];
}
k++;
}
j++;
}
sm[i][id] = strid;
}
i++;
}
//***********************************************************
//测试数组值删除情况
if (0) {
cout << "delete_row的赋值测试:" << endl;
cout << "列名匹配符数量:" << vregexsize << endl;
cout << "列名数量:" << vnamesize << endl;
cout << "行数:" << smrowsize << endl;
cout << "列数:" << smcolsize << endl;
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
cout << "列名匹配符" << i << ":" << vregex[i] << " ";
cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == smcolsize)break;
cout << "数据类型" << i << ":" << vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == smrowsize) break;
cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << scol[i][j] << " ";
cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
//***********************************************************
//把修改后的数组组合成string字符串
strcom = "";
//首先组合列名匹配符和列名
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
strcom += vregex[i];
strcom += vname[i];
//cout << "列名匹配符" << i << ":" << vregex[i] << " ";
//cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
//然后组合行匹配符+列匹配符+正文数据
i = 0;
while (1)
{
if (i == smrowsize) break;
strcom += srow[i];
//cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
strcom += scol[i][j];
strcom += sm[i][j];
//cout << "列匹配符" << i << ":" << scol[i][j] << " ";
//cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
//cout << endl;
i++;
}
//cout << "完成所有数据组合后的strcom:" << strcom << endl;
//***********************************************************
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//这是一个完整一体的string字符串输入txt文档代码
//用于完成最后一步,把strcom输入对应的表
if (1)
{
int outsize, strlength, pathlength;
FILE *fo;
char *path, *ch;
outsize = strb.length();//strb是本自定义函数的表地址
pathlength = outsize;
path = new char[outsize + 1];
outsize = strcom.length();
strlength = outsize;
ch = new char[outsize + 1];
strcpy(path, strb.c_str());//C++中把string字符串转化为字符数组的代码
path[pathlength] = '\0';
strcpy(ch, strcom.c_str());
ch[strlength] = '\0';
//
//sprintf(path, "%s", strpath.c_str());//string字符串赋值给字符数组需要在后面加.c_str()
//cout << path << endl;
//sprintf(ch, "%s", strcom.c_str());
fo = fopen(path, "w");
if (fo == NULL) {//rb读取为二进制
printf("该表不存在!");
return -6;
}
fputs(ch, fo);//向文本文档输入字符串,用fputs()
fclose(fo);
delete[] path;
delete[] ch;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//***********************************************************
//删除申请的内存空间
delete[] smdelete;
//***********************************************************
/
//删除数组的内存空间
delete[] vregex;
delete[] vdatatype;
delete[] vname;
delete[] srow;
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
delete[] scol[i];//把二维数组里的空间一一销毁
delete[] sm[i];
}
delete[] scol;
delete[] sm;
/
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
delete[] setvname;
delete[] setdata;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//-----------------------------------------------------------
//删除申请的内存空间
delete[] wvname;
delete[] wdata;
//-----------------------------------------------------------
delete[] regexst.s;
delete[] regexst.t;
//-----------------------------------------------------------
return 1;
}
//新建列
int private_sql::new_col(string tabname, string colname)
{
string coldatatype;
coldatatype = "CHAR";
string strpath;
strpath = "db\\" + tabname;
strpath = strpath + ".txt";
///
//这里判断要新建列的表是否存在
int coutsize, cpathlength;
FILE *cfi;
char *cpath;
coutsize = strpath.length();
cpathlength = coutsize;
cpath = new char[coutsize + 1];
strcpy(cpath, strpath.c_str());//C++中把string字符串转化为字符数组的代码
cpath[cpathlength] = '\0';
cfi = fopen(cpath, "r");
if (cfi == NULL) {//rb读取为二进制
cout << "该表不存在!" << endl;
return -1;
}
fclose(cfi);
delete[] cpath;
///
///
int k = 0, j = 0, i = 0, z = 0;
//-----------------------------------------------------------
//string *wvname, *wdata;
int ci;//判读是否符合规则的参数,比如和现有的列名是否冲突
//-----------------------------------------------------------
//***********************************************************
int *smdelete;
int id, tf;
string strid, strnullid, strcom, strx, stry;
//***********************************************************
/
string str, strtoo, strtootoo;//保存原始字符串和初次加工去除列名列标的字符串
string strrow, strrowreg, strdatatype;//循环时,临时存放行字符串和和行字符串的匹配码;存放未匹配含数据类型的字符串
string stra, strb;//处理地址
/
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数//列名数与列名匹配字符数相等
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
/
/
//还是重新改一遍查询代码吧,这个函数和其他函数一起循环的时候会出内存错误
/*string tabname
列名:VNAMESIZE
行号:ROWSIZE
列号:COLSIZE
*/
stra = "db\\" + tabname;
strb = stra + ".txt";
str = strget(strb);//调用自定义函数,获取txt文档内容,存为string字符串
if (str == "false") return -1;
/
/*处理列名*//*正则匹配列名匹配符*/
regex_st(str, VNAMESIZE);//调用正则匹配的自定义函数,处理列名
/
//列名列数会比实际列名列数多一位,最后一位列名是匹配后余剩的字符串,将赋值给strtoo,再删除掉
vregexsize = regexst.idtize;//把匹配到的列数赋值给列名的匹配字符数
vnamesize = regexst.idtize;//把匹配到的列数赋值给列名数
smcolsize = regexst.idtize - 1;//列数是列匹配符数减一
vregex = new string[vregexsize];//new动态分配数组大小,这是存放列名匹配码的数组
vname = new string[vregexsize];//new动态分配数组大小,这是存放列名的数组
vdatatype = new string[vregexsize];
/
//处理列名和列名匹配符
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vregex[i] = regexst.t[i];//循环,把正则匹配到的字符一一存入数组(列名和列名匹配码)
vname[i] = regexst.s[i];
i++;
}
//把第一次匹配裁切的字符余下部分加入strtoo
strtoo = vname[vnamesize - 1];
vname[vnamesize - 1] = "";//把列名最后一位清空
/
//处理数据类型
i = 0;
strdatatype = "";
while (1)
{ //一套循环,把所有列名匹配码全拼接到strdatatype,作为预处理的数据
if (i == vregexsize) break;
strdatatype += vregex[i];
i++;
}
//删除内存空间
delete[] regexst.s;
delete[] regexst.t;
//正则匹配大写的数据类型
regex_st(strdatatype, "[A-Z]+");
if (regexst.idtize != 0) {
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vdatatype[i] = regexst.t[i];
i++;
}
}
/
//处理接下来的行与列
/*处理行*/
string * prowregex;//临时的行匹配符存放位置
string * prow;//临时的行数据存放位置
string * pcolregex;//临时的列匹配符存放位置
string * pcol;//临时的列数据存放位置
//关闭正则的数组空间//为免内存泄漏,及各种因为不及时删除内存空间引起的报错,故每次调用函数前都需要运行相应的释放空间代码
delete[] regexst.s;
delete[] regexst.t;
regex_st(strtoo, ROWSIZE);//正则匹配,匹配行
/
//得到行数后,给剩下的数组申请空间
smrowsize = regexst.idsize;//这是行数
//给临时数组申请内存空间
prowregex = new string[smrowsize];//new自定义数组大小,不用多说了
prow = new string[smrowsize];
pcolregex = new string[vnamesize - 1];//这四个都是临时存放数据的数组,这个函数里用完之后delete[] prowregex;删除
pcol = new string[vnamesize - 1];
//给正式的数组申请内存空间
srow = new string[smrowsize];//存放行匹配码的一维数组
scol = new string*[smrowsize];//存放列匹配码的二维数组,行*列才是列匹配码的数量
sm = new string*[smrowsize];//最终结果,这里存放的是真正的数据,行数*列数
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
scol[i] = new string[vnamesize - 1];//同样,把行号数赋值给列匹配码数组的每个维
sm[i] = new string[vnamesize - 1];//把行号数赋值给每个维
}
/
//符合strtoo不为空,才执行下面{}内的代码
if (strtoo == "") {}
else {
/
//符合行数不等于0,才执行下面{}内的代码
if (smrowsize == 0) {}
else {
/
//给临时数组的行匹配符行数据赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
prowregex[i] = regexst.t[i];//把每一行的匹配码字符串存入临时匹配码数组
prow[i] = regexst.s[i];//把每一行的待处理字符串存入临时行字符串数组
i++;
}
/
//给正式数组的行匹配符数组、列匹配符数组、sm数据数组赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
strrowreg = prowregex[i];//把行匹配码存入strrowreg字符串变量,其实这一步有点多此一举,但是任性一把,懒得改了
srow[i] = strrowreg;//存入行匹配字符串
strrow = prow[i];//同样,把待处理的每行字符串存入,strrow字符串变量
//cout << strrow << endl;
if (strrow != "") {
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(strrow, COLSIZE);//循环里调用正则匹配函数,这就是前面为什么要把正则匹配后的结果->未完
//->赶紧赋值给其他变量的原因,它会被覆盖掉
//cout << mysqlsel.vnamesize-1 << endl;
j = 0;//循环里面给j每次循环赋值,不能放外面否则要报错
while (1)
{
if (j == (vnamesize - 1)) break;
//cout << regexst.s[j] << " ";
scol[i][j] = regexst.t[j];//把正则匹配的列匹配码一一赋值给scol二维数组
sm[i][j] = regexst.s[j];//把正则匹配到的数值一一赋值给sm二维数组
j++;
}
}
//cout << endl;
i++;
}
}
/
//删除临时数组的内存空间
delete[] prowregex;
delete[] prow;
delete[] pcolregex;
delete[] pcol;
}
/
/
/
//循环测试
if (0) {
cout << "new_col的赋值测试:" << endl;
cout << "列名匹配符数量:" << vregexsize << endl;
cout << "列名数量:" << vnamesize << endl;
cout << "行数:" << smrowsize << endl;
cout << "列数:" << smcolsize << endl;
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
cout << "列名匹配符" << i << ":" << vregex[i] << " ";
cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == smcolsize)break;
cout << "数据类型" << i << ":" << vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == smrowsize) break;
cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << scol[i][j] << " ";
cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
/
//-----------------------------------------------------------
//以下是分析要新建的colname是否符合规则
i = 0;
ci = 0;
while (1)
{
if (i == smcolsize) break;
if (colname == vname[i]) {
ci = 1;
}
i++;
}
if (ci == 1) return -2;//假如有重复的列名(ci=1),返回-2
//-----------------------------------------------------------
//***********************************************************
//这是解决代码循环的逻辑部分
//***********************************************************
//直接重新组合字符串
//中间,在列名与列名匹配符中,加入新一列列名位置就追加在最后一列
//列名匹配符中间的数字从前一列的列名匹配符中读取
//coldatatype,colname
//***********************************************************
//先从列名匹配符中获取最新一列的数字编码//最新一列时无列名的一列
strx = stry = vregex[vregexsize - 1];
//***********************************************************
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//正则匹配
//由于匹配自定义函数对这个字符串匹配时出了点问题,所以使用手动匹配
//手工的字符匹配不太熟练
//记数字符串里匹配正则的个数,最后的个数i赋值给idtize,idtize是t的个数
int idtize;
string *t;
regex reg("[0-9]+");//加载正则匹配的公式
smatch rsm;
i = 0;
while (regex_search(strx, rsm, reg)) {
strx = rsm.suffix().str();//每次循环,把剩余未匹配的字符串重新加入str字符串变量
i++;
}
idtize = i;
t = new string[i];
//if (idtize == 0) return -10;
i = 0;
strx = stry;
while (regex_search(strx, rsm, reg)) {
for (int j = 0; j < rsm.size(); ++j)
{
t[i] = rsm[j];
}
//cout << endl;
strx = rsm.suffix().str();//每次循环,把剩余未匹配的字符串重新加入str字符串变量
i++;
}
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//***********************************************************
//字符转换,string与int转换
if (idtize == 0)
{
strid = "";
strnullid = "";
}
else {
stry = t[0];
id = stoi(stry.c_str());//string字符串转int数值
strid = to_string(id);//int数值转string字符串
id++;
strnullid = to_string(id);
}
//cout << "新一列的数字编码:" << strid << endl;
//***********************************************************
//组合strcom字符串
//添加列匹配符和列名
strcom = "";
i = 0;
while (1)
{
if (i == (vregexsize + 1)) break;//当列数为7列时,vregexsize=8
if (i == (vregexsize - 1)) {//当i=7时,列数正好在最后一列,没有列名只有匹配字符的一列
//需要替换的列为正常查询的最后一列列名、列匹配符
strcom += vnameregextop;
strcom += coldatatype;//还需要加上相应的数据类型
strcom += strid;//strid即已经处理过的列名匹配符编码
strcom += vnameregexbot;
strcom += colname;
}
else if (i == vregexsize) {//当i在正常查询最后一列再往后一列时(正常这个时候已经超出了数组界限)
//需要把最后一列只有列匹配符没有列名的列在这里补上
strcom += vnameregextop;
strcom += strnullid;//处理过的空列名位置的列名匹配符编码
strcom += vnameregexbot;
//反正最后一位列名也是空值,就不用添加了
}
else {
strcom += vregex[i];
strcom += vname[i];
}
i++;
}
//cout << "添加了列名、列匹配符的strcom:" << strcom << endl;
//添加行匹配符、列匹配符、正文数据、新加列(全设NULL空值)
i = 0;
while (1)
{
if (i == smrowsize) break;
strcom += srow[i];//添加行匹配符
j = 0;
while (1)
{
if (j == (smcolsize + 1)) break;//加1列新列
if (j == smcolsize) {//这是新加的那列
strcom += colregextop;
strcom += strid;
strcom += colregexbot;
strcom += "NULL";
}
else {
strcom += scol[i][j];//列匹配符
strcom += sm[i][j];//正文数据
}
j++;
}
i++;
}
//cout << "添加了正文数据的strcom:" << strcom << endl;
//***********************************************************
//***********************************************************
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//这是一个完整一体的string字符串输入txt文档代码
//用于完成最后一步,把strcom输入对应的表
if (1)
{
int outsize, strlength, pathlength;
FILE *fo;
char *path, *ch;
outsize = strb.length();//strb是本自定义函数的表地址
pathlength = outsize;
path = new char[outsize + 1];
outsize = strcom.length();
strlength = outsize;
ch = new char[outsize + 1];
strcpy(path, strb.c_str());//C++中把string字符串转化为字符数组的代码
path[pathlength] = '\0';
strcpy(ch, strcom.c_str());
ch[strlength] = '\0';
//
//sprintf(path, "%s", strpath.c_str());//string字符串赋值给字符数组需要在后面加.c_str()
//cout << path << endl;
//sprintf(ch, "%s", strcom.c_str());
fo = fopen(path, "w");
if (fo == NULL) {//rb读取为二进制
printf("该表不存在!");
return -6;
}
fputs(ch, fo);//向文本文档输入字符串,用fputs()
fclose(fo);
delete[] path;
delete[] ch;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//***********************************************************
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//删除申请的内存空间
delete[] t;
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//***********************************************************
/
//删除数组的内存空间
delete[] vregex;
delete[] vdatatype;
delete[] vname;
delete[] srow;
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
delete[] scol[i];//把二维数组里的空间一一销毁
delete[] sm[i];
}
delete[] scol;
delete[] sm;
/
//-----------------------------------------------------------
delete[] regexst.s;
delete[] regexst.t;
//-----------------------------------------------------------
///
///
return 1;
}
//删除列
int private_sql::delete_col(string tabname, string colname)
{
//删除列,其实就是重组strcom的时候,不组合要删除的一列
//首先,需要根据要删除的列名,找到对应的这一行列的id(其实就是循环里j的值)
//然后重组strcom的时候,每到该id的列就跳过
//输入值需要,有一个表名,一个列名
//在开头,需要先判断是否存在该表,是否存在该列,不存在就返回报错信息
int i, j, k;
int colci;
string strcom;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//验证是否有该表
string strpath;
strpath = "db\\" + tabname;
strpath = strpath + ".txt";
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//这里判断要删除列的表是否存在
int coutsize, cpathlength;
FILE *cfi;
char *cpath;
coutsize = strpath.length();
cpathlength = coutsize;
cpath = new char[coutsize + 1];
strcpy(cpath, strpath.c_str());//C++中把string字符串转化为字符数组的代码
cpath[cpathlength] = '\0';
cfi = fopen(cpath, "r");
if (cfi == NULL) {//rb读取为二进制
cout << "该表不存在!" << endl;
return -1;
}
fclose(cfi);
delete[] cpath;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//
//这里做查询操作,代码很长
/
string str, strtoo, strtootoo;//保存原始字符串和初次加工去除列名列标的字符串
string strrow, strrowreg, strdatatype;//循环时,临时存放行字符串和和行字符串的匹配码;存放未匹配含数据类型的字符串
string stra, strb;//处理地址
/
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数//列名数与列名匹配字符数相等
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
/
/
//还是重新改一遍查询代码吧,这个函数和其他函数一起循环的时候会出内存错误
/*string tabname
列名:VNAMESIZE
行号:ROWSIZE
列号:COLSIZE
*/
stra = "db\\" + tabname;
strb = stra + ".txt";
str = strget(strb);//调用自定义函数,获取txt文档内容,存为string字符串
if (str == "false") return -1;
//str = strget("db\\1.txt");
/
/*处理列名*//*正则匹配列名匹配符*/
regex_st(str, VNAMESIZE);//调用正则匹配的自定义函数,处理列名
/
//列名列数会比实际列名列数多一位,最后一位列名是匹配后余剩的字符串,将赋值给strtoo,再删除掉
vregexsize = regexst.idtize;//把匹配到的列数赋值给列名的匹配字符数
vnamesize = regexst.idtize;//把匹配到的列数赋值给列名数
smcolsize = regexst.idtize - 1;//列数是列匹配符数减一
vregex = new string[vregexsize];//new动态分配数组大小,这是存放列名匹配码的数组
vname = new string[vregexsize];//new动态分配数组大小,这是存放列名的数组
vdatatype = new string[vregexsize];
/
//处理列名和列名匹配符
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vregex[i] = regexst.t[i];//循环,把正则匹配到的字符一一存入数组(列名和列名匹配码)
vname[i] = regexst.s[i];
i++;
}
//把第一次匹配裁切的字符余下部分加入strtoo
strtoo = vname[vnamesize - 1];
vname[vnamesize - 1] = "";//把列名最后一位清空
/
//处理数据类型
i = 0;
strdatatype = "";
while (1)
{ //一套循环,把所有列名匹配码全拼接到strdatatype,作为预处理的数据
if (i == vregexsize) break;
strdatatype += vregex[i];
i++;
}
//删除内存空间
delete[] regexst.s;
delete[] regexst.t;
//正则匹配大写的数据类型
regex_st(strdatatype, "[A-Z]+");
if (regexst.idtize != 0) {
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vdatatype[i] = regexst.t[i];
i++;
}
}
/
//处理接下来的行与列
/*处理行*/
string * prowregex;//临时的行匹配符存放位置
string * prow;//临时的行数据存放位置
string * pcolregex;//临时的列匹配符存放位置
string * pcol;//临时的列数据存放位置
//关闭正则的数组空间//为免内存泄漏,及各种因为不及时删除内存空间引起的报错,故每次调用函数前都需要运行相应的释放空间代码
delete[] regexst.s;
delete[] regexst.t;
regex_st(strtoo, ROWSIZE);//正则匹配,匹配行
/
//得到行数后,给剩下的数组申请空间
smrowsize = regexst.idsize;//这是行数
//给临时数组申请内存空间
prowregex = new string[smrowsize];//new自定义数组大小,不用多说了
prow = new string[smrowsize];
pcolregex = new string[vnamesize - 1];//这四个都是临时存放数据的数组,这个函数里用完之后delete[] prowregex;删除
pcol = new string[vnamesize - 1];
//给正式的数组申请内存空间
srow = new string[smrowsize];//存放行匹配码的一维数组
scol = new string*[smrowsize];//存放列匹配码的二维数组,行*列才是列匹配码的数量
sm = new string*[smrowsize];//最终结果,这里存放的是真正的数据,行数*列数
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
scol[i] = new string[vnamesize - 1];//同样,把行号数赋值给列匹配码数组的每个维
sm[i] = new string[vnamesize - 1];//把行号数赋值给每个维
}
/
//符合strtoo不为空,才执行下面{}内的代码
if (strtoo == "") {}
else {
/
//符合行数不等于0,才执行下面{}内的代码
if (smrowsize == 0) {}
else {
/
//给临时数组的行匹配符行数据赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
prowregex[i] = regexst.t[i];//把每一行的匹配码字符串存入临时匹配码数组
prow[i] = regexst.s[i];//把每一行的待处理字符串存入临时行字符串数组
i++;
}
/
//给正式数组的行匹配符数组、列匹配符数组、sm数据数组赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
strrowreg = prowregex[i];//把行匹配码存入strrowreg字符串变量,其实这一步有点多此一举,但是任性一把,懒得改了
srow[i] = strrowreg;//存入行匹配字符串
strrow = prow[i];//同样,把待处理的每行字符串存入,strrow字符串变量
//cout << strrow << endl;
if (strrow != "") {
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(strrow, COLSIZE);//循环里调用正则匹配函数,这就是前面为什么要把正则匹配后的结果->未完
//->赶紧赋值给其他变量的原因,它会被覆盖掉
//cout << mysqlsel.vnamesize-1 << endl;
j = 0;//循环里面给j每次循环赋值,不能放外面否则要报错
while (1)
{
if (j == (vnamesize - 1)) break;
//cout << regexst.s[j] << " ";
scol[i][j] = regexst.t[j];//把正则匹配的列匹配码一一赋值给scol二维数组
sm[i][j] = regexst.s[j];//把正则匹配到的数值一一赋值给sm二维数组
j++;
}
}
//cout << endl;
i++;
}
}
}
/
//删除临时数组的内存空间
delete[] prowregex;
delete[] prow;
delete[] pcolregex;
delete[] pcol;
/
/
/
//循环测试
if (0) {
cout << "delete_row的赋值测试:" << endl;
cout << "列名匹配符数量:" << vregexsize << endl;
cout << "列名数量:" << vnamesize << endl;
cout << "行数:" << smrowsize << endl;
cout << "列数:" << smcolsize << endl;
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
cout << "列名匹配符" << i << ":" << vregex[i] << " ";
cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == smcolsize)break;
cout << "数据类型" << i << ":" << vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == smrowsize) break;
cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << scol[i][j] << " ";
cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
//
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//这里判断要删除的列是否存在
colci = 0;
i = 0;
while (1)
{
if (i == smcolsize) break;
if (vname[i] == colname)
{
colci++;
}
i++;
}
if (colci == 0) return -2;//假如参数没有在循环中加1,还是0的话,说明输入的列名错误,该列不存在
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//###########################################################
//这里实现找到要删列的功能,不新建参数了,还是用colci
i = 0;
while (1)
{
if (i == smcolsize) break;
if (vname[i] == colname)
{
colci = i;//当列名与输入的列名匹配的时候,把i赋值给colci
}
i++;
}
//cout << "colci=" << colci << endl;
//###########################################################
//***********************************************************
//下面重组strcom
strcom = "";
//列名匹配符和列名
i = 0;
while (1)
{
if (i == vregexsize) break;
if (colci == i) {}
else {
strcom += vregex[i];
strcom += vname[i];
}
i++;
}
//行匹配符和列匹配符与正文数据
i = 0;
while (1)
{
if (i == smrowsize) break;
strcom += srow[i];
j = 0;
while (1)
{
if (j == smcolsize) break;
if (j == colci) {}
else {
strcom += scol[i][j];
strcom += sm[i][j];
}
j++;
}
i++;
}
//***********************************************************
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//这是一个完整一体的string字符串输入txt文档代码
//用于完成最后一步,把strcom输入对应的表
if (1)
{
int outsize, strlength, pathlength;
FILE *fo;
char *path, *ch;
outsize = strb.length();//strb是本自定义函数的表地址
pathlength = outsize;
path = new char[outsize + 1];
outsize = strcom.length();
strlength = outsize;
ch = new char[outsize + 1];
strcpy(path, strb.c_str());//C++中把string字符串转化为字符数组的代码
path[pathlength] = '\0';
strcpy(ch, strcom.c_str());
ch[strlength] = '\0';
//
//sprintf(path, "%s", strpath.c_str());//string字符串赋值给字符数组需要在后面加.c_str()
//cout << path << endl;
//sprintf(ch, "%s", strcom.c_str());
fo = fopen(path, "w");
if (fo == NULL) {//rb读取为二进制
printf("该表不存在!");
return -6;
}
fputs(ch, fo);//向文本文档输入字符串,用fputs()
fclose(fo);
delete[] path;
delete[] ch;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/
//查询的清理
//删除数组的内存空间
delete[] vregex;
delete[] vdatatype;
delete[] vname;
delete[] srow;
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
delete[] scol[i];//把二维数组里的空间一一销毁
delete[] sm[i];
}
delete[] scol;
delete[] sm;
/
/
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
/
return 1;
}
//查询表1
int private_sql::select_table(tab * s, string tabname)
{
//这是从其他地方直接复用过来的代码,有部分注释会不对
int i, j, k;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//验证是否有该表
string strpath;
strpath = "db\\" + tabname;
strpath = strpath + ".txt";
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//这里判断要查询的表是否存在
int coutsize, cpathlength;
FILE *cfi;
char *cpath;
coutsize = strpath.length();
cpathlength = coutsize;
cpath = new char[coutsize + 1];
strcpy(cpath, strpath.c_str());//C++中把string字符串转化为字符数组的代码
cpath[cpathlength] = '\0';
cfi = fopen(cpath, "r");
if (cfi == NULL) {//rb读取为二进制
cout << "该表不存在!" << endl;
return -1;
}
fclose(cfi);
delete[] cpath;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//
//这里做查询操作,代码很长
/
string str, strtoo, strtootoo;//保存原始字符串和初次加工去除列名列标的字符串
string strrow, strrowreg, strdatatype;//循环时,临时存放行字符串和和行字符串的匹配码;存放未匹配含数据类型的字符串
string stra, strb;//处理地址
/
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数//列名数与列名匹配字符数相等
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
/
/
//还是重新改一遍查询代码吧,这个函数和其他函数一起循环的时候会出内存错误
/*string tabname
列名:VNAMESIZE
行号:ROWSIZE
列号:COLSIZE
*/
stra = "db\\" + tabname;
strb = stra + ".txt";
str = strget(strb);//调用自定义函数,获取txt文档内容,存为string字符串
if (str == "false") return -1;
//str = strget("db\\1.txt");
/
/*处理列名*//*正则匹配列名匹配符*/
regex_st(str, VNAMESIZE);//调用正则匹配的自定义函数,处理列名
/
//列名列数会比实际列名列数多一位,最后一位列名是匹配后余剩的字符串,将赋值给strtoo,再删除掉
vregexsize = regexst.idtize;//把匹配到的列数赋值给列名的匹配字符数
vnamesize = regexst.idtize;//把匹配到的列数赋值给列名数
smcolsize = regexst.idtize - 1;//列数是列匹配符数减一
vregex = new string[vregexsize];//new动态分配数组大小,这是存放列名匹配码的数组
vname = new string[vregexsize];//new动态分配数组大小,这是存放列名的数组
vdatatype = new string[vregexsize];
//QQQQQQQQQQQQQQQQQQQQQQQQQ数组通过指针返回
s->vregexsize = regexst.idtize;//把匹配到的列数赋值给列名的匹配字符数
s->vnamesize = regexst.idtize;//把匹配到的列数赋值给列名数
s->smcolsize = regexst.idtize - 1;//列数是列匹配符数减一
s->vregex = new string[s->vregexsize];//new动态分配数组大小,这是存放列名匹配码的数组
s->vname = new string[s->vregexsize];//new动态分配数组大小,这是存放列名的数组
s->vdatatype = new string[s->vregexsize];
//QQQQQQQQQQQQQQQQQQQQQQQQQ
/
//处理列名和列名匹配符
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vregex[i] = regexst.t[i];//循环,把正则匹配到的字符一一存入数组(列名和列名匹配码)
vname[i] = regexst.s[i];
//QQQQQQQQQQQQQQQQQQQQQQQQQ
s->vregex[i] = regexst.t[i];//循环,把正则匹配到的字符一一存入数组(列名和列名匹配码)
s->vname[i] = regexst.s[i];
//QQQQQQQQQQQQQQQQQQQQQQQQQ
i++;
}
//把第一次匹配裁切的字符余下部分加入strtoo
strtoo = vname[vnamesize - 1];
vname[vnamesize - 1] = "";//把列名最后一位清空
//QQQQQQQQQQQQQQQQQQQQQQQQQ
s->vname[vnamesize - 1] = "";
//QQQQQQQQQQQQQQQQQQQQQQQQQ
/
//处理数据类型
i = 0;
strdatatype = "";
while (1)
{ //一套循环,把所有列名匹配码全拼接到strdatatype,作为预处理的数据
if (i == vregexsize) break;
strdatatype += vregex[i];
i++;
}
//删除内存空间
delete[] regexst.s;
delete[] regexst.t;
//正则匹配大写的数据类型
regex_st(strdatatype, "[A-Z]+");
if (regexst.idtize != 0) {
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vdatatype[i] = regexst.t[i];
//QQQQQQQQQQQQQQQQQQQQQQQQQ
s->vdatatype[i] = regexst.t[i];
//QQQQQQQQQQQQQQQQQQQQQQQQQ
i++;
}
}
/
//处理接下来的行与列
/*处理行*/
string * prowregex;//临时的行匹配符存放位置
string * prow;//临时的行数据存放位置
string * pcolregex;//临时的列匹配符存放位置
string * pcol;//临时的列数据存放位置
//关闭正则的数组空间//为免内存泄漏,及各种因为不及时删除内存空间引起的报错,故每次调用函数前都需要运行相应的释放空间代码
delete[] regexst.s;
delete[] regexst.t;
regex_st(strtoo, ROWSIZE);//正则匹配,匹配行
/
//得到行数后,给剩下的数组申请空间
smrowsize = regexst.idsize;//这是行数
//QQQQQQQQQQQQQQQQQQQQQQQQQ
s->smrowsize = regexst.idsize;//这是行数
//QQQQQQQQQQQQQQQQQQQQQQQQQ
//给临时数组申请内存空间
prowregex = new string[smrowsize];//new自定义数组大小,不用多说了
prow = new string[smrowsize];
pcolregex = new string[vnamesize - 1];//这四个都是临时存放数据的数组,这个函数里用完之后delete[] prowregex;删除
pcol = new string[vnamesize - 1];
//给正式的数组申请内存空间
srow = new string[smrowsize];//存放行匹配码的一维数组
scol = new string*[smrowsize];//存放列匹配码的二维数组,行*列才是列匹配码的数量
sm = new string*[smrowsize];//最终结果,这里存放的是真正的数据,行数*列数
//QQQQQQQQQQQQQQQQQQQQQQQQQ
s->srow = new string[smrowsize];//存放行匹配码的一维数组
s->scol = new string*[smrowsize];//存放列匹配码的二维数组,行*列才是列匹配码的数量
s->sm = new string*[smrowsize];//最终结果,这里存放的是真正的数据,行数*列数
//QQQQQQQQQQQQQQQQQQQQQQQQQ
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
scol[i] = new string[vnamesize - 1];//同样,把行号数赋值给列匹配码数组的每个维
sm[i] = new string[vnamesize - 1];//把行号数赋值给每个维
//QQQQQQQQQQQQQQQQQQQQQQQQQ
s->scol[i] = new string[vnamesize - 1];
s->sm[i] = new string[vnamesize - 1];
//QQQQQQQQQQQQQQQQQQQQQQQQQ
}
/
//符合strtoo不为空,才执行下面{}内的代码
if (strtoo == "") {}
else {
/
//符合行数不等于0,才执行下面{}内的代码
if (smrowsize == 0) {}
else {
/
//给临时数组的行匹配符行数据赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
prowregex[i] = regexst.t[i];//把每一行的匹配码字符串存入临时匹配码数组
prow[i] = regexst.s[i];//把每一行的待处理字符串存入临时行字符串数组
i++;
}
/
//给正式数组的行匹配符数组、列匹配符数组、sm数据数组赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
strrowreg = prowregex[i];//把行匹配码存入strrowreg字符串变量,其实这一步有点多此一举,但是任性一把,懒得改了
srow[i] = strrowreg;//存入行匹配字符串
//QQQQQQQQQQQQQQQQQQQQQQQQQ
s->srow[i] = strrowreg;
//QQQQQQQQQQQQQQQQQQQQQQQQQ
strrow = prow[i];//同样,把待处理的每行字符串存入,strrow字符串变量
//cout << strrow << endl;
if (strrow != "") {
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(strrow, COLSIZE);//循环里调用正则匹配函数,这就是前面为什么要把正则匹配后的结果->未完
//->赶紧赋值给其他变量的原因,它会被覆盖掉
//cout << mysqlsel.vnamesize-1 << endl;
j = 0;//循环里面给j每次循环赋值,不能放外面否则要报错
while (1)
{
if (j == (vnamesize - 1)) break;
//cout << regexst.s[j] << " ";
scol[i][j] = regexst.t[j];//把正则匹配的列匹配码一一赋值给scol二维数组
sm[i][j] = regexst.s[j];//把正则匹配到的数值一一赋值给sm二维数组
//QQQQQQQQQQQQQQQQQQQQQQQQQ
s->scol[i][j] = regexst.t[j];
s->sm[i][j] = regexst.s[j];
//QQQQQQQQQQQQQQQQQQQQQQQQQ
j++;
}
}
//cout << endl;
i++;
}
}
}
/
//删除临时数组的内存空间
delete[] prowregex;
delete[] prow;
delete[] pcolregex;
delete[] pcol;
/
/
/
//循环测试
if (0) {
cout << "select_table的赋值测试:" << endl;
cout << "列名匹配符数量:" << vregexsize << endl;
cout << "列名数量:" << vnamesize << endl;
cout << "行数:" << smrowsize << endl;
cout << "列数:" << smcolsize << endl;
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
cout << "列名匹配符" << i << ":" << vregex[i] << " ";
cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == smcolsize)break;
cout << "数据类型" << i << ":" << vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == smrowsize) break;
cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << scol[i][j] << " ";
cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
//
/
//查询的清理
//删除数组的内存空间
delete[] vregex;
delete[] vdatatype;
delete[] vname;
delete[] srow;
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
delete[] scol[i];//把二维数组里的空间一一销毁
delete[] sm[i];
}
delete[] scol;
delete[] sm;
/
/
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
/
return 1;
}
//显示读出的文件2
int private_sql::show_tab(tab * s)
{
//循环测试
if (1) {
cout << "select_table的赋值测试:" << endl;
cout << "列名匹配符数量:" << s->vregexsize << endl;
cout << "列名数量:" << s->vnamesize << endl;
cout << "行数:" << s->smrowsize << endl;
cout << "列数:" << s->smcolsize << endl;
int j = 0;
int i = 0;
while (1)
{
if (i == s->vregexsize) break;
cout << "列名匹配符" << i << ":" << s->vregex[i] << " ";
cout << "列名" << i << ":" << s->vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == s->smcolsize)break;
cout << "数据类型" << i << ":" << s->vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == s->smrowsize) break;
cout << "行匹配符" << i << ":" << s->srow[i] << endl;
j = 0;
while (1)
{
if (j == (s->vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << s->scol[i][j] << " ";
cout << "正文数据" << i << ":" << s->sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
return 1;
}
//清理结构体变量3
int private_sql::clean_tab(tab * s)
{
int i;
/
//查询的清理
//删除数组的内存空间
delete[] s->vregex;
delete[] s->vdatatype;
delete[] s->vname;
delete[] s->srow;
for (i = 0; i < s->smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
delete[] s->scol[i];//把二维数组里的空间一一销毁
delete[] s->sm[i];
}
delete[] s->scol;
delete[] s->sm;
/
return 1;
}
//查询表,显示
int private_sql::select_table_show(string tabname)
{
//这是从其他地方直接复用过来的代码,有部分注释会不对
int i, j, k;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//验证是否有该表
string strpath;
strpath = "db\\" + tabname;
strpath = strpath + ".txt";
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//这里判断要查询的表是否存在
int coutsize, cpathlength;
FILE *cfi;
char *cpath;
coutsize = strpath.length();
cpathlength = coutsize;
cpath = new char[coutsize + 1];
strcpy(cpath, strpath.c_str());//C++中把string字符串转化为字符数组的代码
cpath[cpathlength] = '\0';
cfi = fopen(cpath, "r");
if (cfi == NULL) {//rb读取为二进制
cout << "该表不存在!" << endl;
return -1;
}
fclose(cfi);
delete[] cpath;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//
//这里做查询操作,代码很长
/
string str, strtoo, strtootoo;//保存原始字符串和初次加工去除列名列标的字符串
string strrow, strrowreg, strdatatype;//循环时,临时存放行字符串和和行字符串的匹配码;存放未匹配含数据类型的字符串
string stra, strb;//处理地址
/
int vregexsize;//保存列名的匹配字符数//列名的匹配字符会比行名多一位为的是分割最后一位列名与正文
int vnamesize;//保存列名数//列名数与列名匹配字符数相等
string * vregex;//保存列名的匹配字符
string * vdatatype;//保存数据类型
string * vname;//保存列名
int smrowsize;//保存行号数
int smcolsize;//保存列号数
string * srow;//srow存放行匹配字符串,行匹配字符只有行
string ** scol;//scol存放列匹配字符串,列匹配字符是行*列
string ** sm;//第二个数组参数表示行,第三个参数表示列
/
/
//还是重新改一遍查询代码吧,这个函数和其他函数一起循环的时候会出内存错误
/*string tabname
列名:VNAMESIZE
行号:ROWSIZE
列号:COLSIZE
*/
stra = "db\\" + tabname;
strb = stra + ".txt";
str = strget(strb);//调用自定义函数,获取txt文档内容,存为string字符串
if (str == "false") return -1;
//str = strget("db\\1.txt");
/
/*处理列名*//*正则匹配列名匹配符*/
regex_st(str, VNAMESIZE);//调用正则匹配的自定义函数,处理列名
/
//列名列数会比实际列名列数多一位,最后一位列名是匹配后余剩的字符串,将赋值给strtoo,再删除掉
vregexsize = regexst.idtize;//把匹配到的列数赋值给列名的匹配字符数
vnamesize = regexst.idtize;//把匹配到的列数赋值给列名数
smcolsize = regexst.idtize - 1;//列数是列匹配符数减一
vregex = new string[vregexsize];//new动态分配数组大小,这是存放列名匹配码的数组
vname = new string[vregexsize];//new动态分配数组大小,这是存放列名的数组
vdatatype = new string[vregexsize];
/
//处理列名和列名匹配符
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vregex[i] = regexst.t[i];//循环,把正则匹配到的字符一一存入数组(列名和列名匹配码)
vname[i] = regexst.s[i];
i++;
}
//把第一次匹配裁切的字符余下部分加入strtoo
strtoo = vname[vnamesize - 1];
vname[vnamesize - 1] = "";//把列名最后一位清空
/
//处理数据类型
i = 0;
strdatatype = "";
while (1)
{ //一套循环,把所有列名匹配码全拼接到strdatatype,作为预处理的数据
if (i == vregexsize) break;
strdatatype += vregex[i];
i++;
}
//删除内存空间
delete[] regexst.s;
delete[] regexst.t;
//正则匹配大写的数据类型
regex_st(strdatatype, "[A-Z]+");
if (regexst.idtize != 0) {
i = 0;
while (1)
{
if (i == regexst.idtize) break;
vdatatype[i] = regexst.t[i];
i++;
}
}
/
//处理接下来的行与列
/*处理行*/
string * prowregex;//临时的行匹配符存放位置
string * prow;//临时的行数据存放位置
string * pcolregex;//临时的列匹配符存放位置
string * pcol;//临时的列数据存放位置
//关闭正则的数组空间//为免内存泄漏,及各种因为不及时删除内存空间引起的报错,故每次调用函数前都需要运行相应的释放空间代码
delete[] regexst.s;
delete[] regexst.t;
regex_st(strtoo, ROWSIZE);//正则匹配,匹配行
/
//得到行数后,给剩下的数组申请空间
smrowsize = regexst.idsize;//这是行数
//给临时数组申请内存空间
prowregex = new string[smrowsize];//new自定义数组大小,不用多说了
prow = new string[smrowsize];
pcolregex = new string[vnamesize - 1];//这四个都是临时存放数据的数组,这个函数里用完之后delete[] prowregex;删除
pcol = new string[vnamesize - 1];
//给正式的数组申请内存空间
srow = new string[smrowsize];//存放行匹配码的一维数组
scol = new string*[smrowsize];//存放列匹配码的二维数组,行*列才是列匹配码的数量
sm = new string*[smrowsize];//最终结果,这里存放的是真正的数据,行数*列数
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
scol[i] = new string[vnamesize - 1];//同样,把行号数赋值给列匹配码数组的每个维
sm[i] = new string[vnamesize - 1];//把行号数赋值给每个维
}
/
//符合strtoo不为空,才执行下面{}内的代码
if (strtoo == "") {}
else {
/
//符合行数不等于0,才执行下面{}内的代码
if (smrowsize == 0) {}
else {
/
//给临时数组的行匹配符行数据赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
prowregex[i] = regexst.t[i];//把每一行的匹配码字符串存入临时匹配码数组
prow[i] = regexst.s[i];//把每一行的待处理字符串存入临时行字符串数组
i++;
}
/
//给正式数组的行匹配符数组、列匹配符数组、sm数据数组赋值
i = 0;
while (1)
{
if (i == smrowsize) break;
strrowreg = prowregex[i];//把行匹配码存入strrowreg字符串变量,其实这一步有点多此一举,但是任性一把,懒得改了
srow[i] = strrowreg;//存入行匹配字符串
strrow = prow[i];//同样,把待处理的每行字符串存入,strrow字符串变量
//cout << strrow << endl;
if (strrow != "") {
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
regex_st(strrow, COLSIZE);//循环里调用正则匹配函数,这就是前面为什么要把正则匹配后的结果->未完
//->赶紧赋值给其他变量的原因,它会被覆盖掉
//cout << mysqlsel.vnamesize-1 << endl;
j = 0;//循环里面给j每次循环赋值,不能放外面否则要报错
while (1)
{
if (j == (vnamesize - 1)) break;
//cout << regexst.s[j] << " ";
scol[i][j] = regexst.t[j];//把正则匹配的列匹配码一一赋值给scol二维数组
sm[i][j] = regexst.s[j];//把正则匹配到的数值一一赋值给sm二维数组
j++;
}
}
//cout << endl;
i++;
}
}
}
/
//删除临时数组的内存空间
delete[] prowregex;
delete[] prow;
delete[] pcolregex;
delete[] pcol;
/
/
/
//循环测试
if (1) {
cout << "select_table的赋值测试:" << endl;
cout << "列名匹配符数量:" << vregexsize << endl;
cout << "列名数量:" << vnamesize << endl;
cout << "行数:" << smrowsize << endl;
cout << "列数:" << smcolsize << endl;
j = 0;
i = 0;
while (1)
{
if (i == vregexsize) break;
cout << "列名匹配符" << i << ":" << vregex[i] << " ";
cout << "列名" << i << ":" << vname[i] << endl;
i++;
}
i = 0;
while (1)
{
if (i == smcolsize)break;
cout << "数据类型" << i << ":" << vdatatype[i] << endl;
i++;
}
cout << endl;
i = 0;
while (1)
{
if (i == smrowsize) break;
cout << "行匹配符" << i << ":" << srow[i] << endl;
j = 0;
while (1)
{
if (j == (vnamesize - 1)) break;
cout << "列匹配符" << i << ":" << scol[i][j] << " ";
cout << "正文数据" << i << ":" << sm[i][j] << endl;//
j++;
}
cout << endl;
i++;
}
}
//
/
//查询的清理
//删除数组的内存空间
delete[] vregex;
delete[] vdatatype;
delete[] vname;
delete[] srow;
for (i = 0; i < smrowsize; i++) {//里面作为判断值的是行数,i小于行数继续执行
delete[] scol[i];//把二维数组里的空间一一销毁
delete[] sm[i];
}
delete[] scol;
delete[] sm;
/
/
//关闭正则的数组
delete[] regexst.s;
delete[] regexst.t;
/
return 1;
}
//调试工具
int private_sql::set_sql()
{
string z;
string tabname, sqlwhere, sqlset, sqlvname, sqldatatype;
//还是弃用mysql_sel这个函数,全局变量容易出错
//还需要在新建表和添加一行当中修改代码
//
int i = 0;
while (1)
{
//if (i == 1) break;
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 << "10:查询表" << endl;
cout << "0:退出" << endl;
getline(cin, z);
if (z == "1") {
cout << "请输入表名:" << endl;
getline(cin, tabname);//"INT id CHAR name CHAR sex CHAR a INT b INT c INT d"
cout << "请输入sqlset语句(规则【列名 列名 列名】,如:id name sex a b c d)):" << endl;
getline(cin, sqlset);
if (a.new_table(tabname, sqlset)>0)
{
cout << "新建成功!" << endl;
}
else
{
cout << "新建失败!" << endl;
}
}
else if (z == "2") {
cout << "请输入要删除的表名:" << endl;
getline(cin, tabname);
if (a.delete_table(tabname)>0)
{
cout << "删除成功!" << endl;
}
else
{
cout << "删除失败!" << endl;
}
}
else if (z == "3") {
cout << "请输入表名:" << endl;
getline(cin, tabname);
cout << "请输入sqlwhere语句(规则【列名 列名 列名 数值 数值 数值】,如:id name sex 5 朱军 男):" << endl;
getline(cin, sqlwhere);
if (a.new_row(tabname, sqlwhere)>0) {
cout << "新建行成功!" << endl;
}
else {
cout << "新建行失败!" << endl;
}
}
else if (z == "4") {
cout << "请输入表名:" << endl;
getline(cin, tabname);
cout << "请输入sqlwhere语句(规则:【列名 列名 列名 数值 数值 数值】,如:id name a b d 2 张三 NULL NULL 17):" << endl;
getline(cin, sqlwhere);
if (a.delete_row(tabname, sqlwhere) > 0) {
cout << "删除行成功!" << endl;
}
else {
cout << "删除行失败!" << endl;
}
}
else if (z == "5") {
cout << "请输入表名:" << endl;
getline(cin, tabname);
cout << "请输入sqlset语句(规则:【列名 列名 列名 数值 数值 数值】,如:id name a b d 2 张三 NULL NULL 17):" << endl;
getline(cin, sqlset);
cout << "请输入sqlwhere语句(规则:【列名 列名 列名 数值 数值 数值】,如:id name a b d 2 张三 NULL NULL 17):" << endl;
getline(cin, sqlwhere);
if (a.updata_data(tabname, sqlset, sqlwhere) > 0) {
cout << "更新数据成功!" << endl;
}
else {
cout << "更新数据失败!" << endl;
}
}
else if (z == "6") {
cout << "请输入表名:" << endl;
getline(cin, tabname);
cout << "请输入sqlvname语句(规则:【列名】,如:myname,注:一次,只可插入一列):" << endl;
getline(cin, sqlvname);
if (a.new_col(tabname, sqlvname) > 0) {
cout << "新建列成功!" << endl;
}
else {
cout << "新建列失败!" << endl;
}
}
else if (z == "7") {
cout << "请输入表名:" << endl;
getline(cin, tabname);
cout << "请输入sqlvname语句(规则:【列名】,如:myname,注:一次,只可删除一列):" << endl;
getline(cin, sqlvname);
if (a.delete_col(tabname, sqlvname) > 0) {
cout << "删除列成功!" << endl;
}
else {
cout << "删除列失败!" << endl;
}
}
else if (z == "10") {
cout << "请输入表名:" << endl;
getline(cin, tabname);
a.select_table_show(tabname);
}
else if (z == "0")
{
break;//跳出循环
}
else
{
cout << "您输入有误!" << endl;
}
i++;
}
return 1;
}