VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 465|回复: 2

[原创] 数据库之本地数据库

[复制链接]
75_avatar_middle
最佳答案
0 
在线会员 发表于 2019-5-10 10:33:40 | 显示全部楼层 |阅读模式
数据库技术戏称是程序里面的体力劳动,实际上它也有个技术坎,你突破了这个坎,它就是体力活,没有掌握就是脑力活。
这里示范是MDB数据库的常用操作,建库,建表,插入数据,修改数据,显示数据。没有示范删除,那只是一句语句而已。
有些东西常久不用,就会遗忘,好记性不如烂笔头,这里也可备用,实在想不起就来查一查。
操作本地数据库,这里没用SQL语句,SQL在网络数据库里弄吧。仅仅只是示范Jet4.0引擎。
方法来自MSDN,只不过我把集中体现在下面一个示例中。实际运用中,看到都能回忆起来,哦,原来是这样操作地。
引入库:
ado  用于数据操作
adox用于数据管理
关于这两库的资料已经多的不能再多了,不明白就上网找,满大街都是。
例程:

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <Ole2.h>
#include <icrsint.h>
#include<oledberr.h>
//指针和对象释放
#define SAFE_RELEASE_P(p){ if(p) { (p)->Release();(p)=NULL;}}
#define SAFE_RELEASE_O(p){ if(p) { (p).Release();}}
//如果#import显示无法打开源文件msadox.tlh,选菜单生成,无论对错,重新生成解决方案即可。
#import "C:\Program Files (x86)\Common Files\system\ado\msado15.dll" rename("EOF", "EndOfFile")  
#import "C:\Program Files (x86)\Common Files\system\ado\msadox.dll"  no_namespace
using namespace std;
bool createdatabase(string dbname) {
        bool result = false;
        stringstream o;
        o << "Provider = 'Microsoft.JET.OLEDB.4.0';Data source = " << dbname;
        string connstr = o.str();
        _CatalogPtr pCatalog = NULL;
        _bstr_t strcnn(connstr.c_str());
        try {
                HRESULT hr = pCatalog.CreateInstance(__uuidof(Catalog));
                if (FAILED(hr)) _com_issue_error(hr);
                pCatalog->Create(strcnn);
                cout << "本地数据库:"<< dbname << " 已建立!" << endl;
                result = true;
        }
        catch (_com_error &e) {
                //错误号包含在 #include<oledberr.h>中
                cout << "异常返回码=0x" << hex << e.Error() << dec << endl;
                _bstr_t bstrSource(e.Source());
                _bstr_t bstrDescription(e.Description());
                cout << "源  : " << (LPCSTR)bstrSource << endl;
                cout << "描述: " << (LPCSTR)bstrDescription << endl;
        }
        catch (...) {
                cout << " CreateDatabaseX 出错!!." << endl;
        }
        SAFE_RELEASE_O(pCatalog);
        return result;
}
bool buildtable(string dbname,string tabname)
{
        bool result = false;
        stringstream o;
        o << "Provider = 'Microsoft.JET.OLEDB.4.0';Data source = " << dbname;
        string connstr = o.str();
        _bstr_t   strcnn(connstr.c_str());
        _TablePtr pTable = NULL;
        _IndexPtr pIndex = NULL;
        _CatalogPtr pCatalog = NULL;
        _KeyPtr pKeyPrimary = NULL;
        HRESULT hr = S_OK;
        try {
                hr = pTable.CreateInstance(__uuidof(Table));
                if (FAILED(hr)) _com_issue_error(hr);
                hr = pIndex.CreateInstance(__uuidof(Index));
                if (FAILED(hr)) _com_issue_error(hr);
                hr = pCatalog.CreateInstance(__uuidof (Catalog));
                if (FAILED(hr)) _com_issue_error(hr);

                pCatalog->PutActiveConnection(strcnn);
                // 定义表,追加到目录.  
                pTable->Name = _bstr_t(tabname.c_str());
                hr = pTable->Columns->Append("编号", adInteger, 0);
                hr = pTable->Columns->Append("姓名", adVarWChar, 30);
                hr = pTable->Columns->Append("性别", adInteger, 0);
                hr = pTable->Columns->Append("年龄", adInteger, 0);
                hr = pTable->Columns->Append("班级", adInteger, 0);
                hr = pTable->Columns->Append("住址", adVarWChar, 50);
                hr = pCatalog->Tables->Append(_variant_t((IDispatch *)pTable));
                if (FAILED(hr)) _com_issue_error(hr);
                cout << "表" << pTable->Name << "被追加!" << endl;
                // 定义辅索引.  
                pIndex->Name = _bstr_t("按名索引");
                pIndex->Columns->Append("姓名", adInteger, 0);
                // 添加索引到表中.  
                hr = pCatalog->Tables->GetItem(tabname.c_str())->Indexes->Append(_variant_t((IDispatch *)pIndex));
                if (FAILED(hr)) _com_issue_error(hr);
                cout << "索引[" << pIndex->Name << "]被添加!" << endl;
                //定义主索引.  
                hr = pKeyPrimary.CreateInstance(__uuidof(Key));
                pKeyPrimary->Name = "主键";
                pKeyPrimary->Type = adKeyPrimary;
                pKeyPrimary->RelatedTable = _bstr_t(tabname.c_str());;
                pKeyPrimary->Columns->Append("编号", adVarWChar, 0);
                pKeyPrimary->Columns->Append("班级", adVarWChar, 0);
                pKeyPrimary->UpdateRule = adRICascade;
                _variant_t vOptional;
                vOptional.vt = VT_ERROR;
                vOptional.scode = DISP_E_PARAMNOTFOUND;
                hr=pCatalog->Tables->GetItem(tabname.c_str())->Keys->
                        Append(_variant_t((IDispatch *)pKeyPrimary),adKeyPrimary, vOptional, L"", L"");
                if (FAILED(hr)) _com_issue_error(hr);
                cout << "索引[" << pKeyPrimary->Name << "]被添加!" << endl;
                result = true;
        }
        catch (_com_error &e) {
                //错误号包含在 #include<oledberr.h>中
                cout << "异常返回码=0x" << hex << e.Error() << dec << endl;
                _bstr_t bstrSource(e.Source());
                _bstr_t bstrDescription(e.Description());
                cout << "源  : " << (LPCSTR)bstrSource << endl;
                cout << "描述: " << (LPCSTR)bstrDescription << endl;
        }
        catch (...) {
                cout << "建立表和索引产生未知错误!...." << endl;
        }
        SAFE_RELEASE_O(pKeyPrimary);
        SAFE_RELEASE_O(pIndex);
        SAFE_RELEASE_O(pTable);
        SAFE_RELEASE_O(pCatalog);
        return result;
}
void appenddata(string dbname,string tabname) {
        struct _data{
                int no;
                wstring name;
                int sex;
                int howold;
                int classgroup;
                wstring address;
        };
        _data data[] = {
                { 1,L"张三",1,8,301,L"城中村1" },
                { 2,L"李四",1,7,301,L"城中村1" },
                { 3,L"王五",1,8,301,L"城中村2" },
                { 4,L"赵六",1,8,301,L"城中村2" },
                { 5,L"钱七",1,9,301,L"城中村2" },
                { 6,L"宋八",1,8,301,L"城中村3" },
        };
        class CDemoRs : public CADORecordBinding {
                BEGIN_ADO_BINDING(CDemoRs)
                        ADO_NUMERIC_ENTRY(1, adInteger,  m_bh,     0,0, m_bhStatus,TRUE)
                        ADO_VARIABLE_LENGTH_ENTRY2(2, adVarWChar, m_name,sizeof(m_name), m_nameStatus,TRUE)
                        ADO_NUMERIC_ENTRY(3, adInteger,  m_sex,    0,0, m_sexStatus,    TRUE)
                        ADO_NUMERIC_ENTRY(4, adInteger,  m_howold, 0,0, m_howoldStatus, TRUE)
                        ADO_NUMERIC_ENTRY(5, adInteger,  m_class,  0,0, m_classStatus,  TRUE)
                        ADO_VARIABLE_LENGTH_ENTRY2(6, adVarWChar, m_address,sizeof(m_address),m_addressStatus,TRUE)
                END_ADO_BINDING()
        public:
                int   m_bh;
                ULONG m_bhStatus;
                TCHAR m_name[30];
                ULONG m_nameStatus;
                int   m_sex;
                ULONG m_sexStatus;
                int   m_howold;
                ULONG m_howoldStatus;
                int   m_class;
                ULONG m_classStatus;
                TCHAR m_address[50];
                ULONG m_addressStatus;
        };
        IADORecordBinding *pIrb = NULL;
        CDemoRs rs;
        stringstream o;
        o << "Provider = 'Microsoft.JET.OLEDB.4.0';Data source = " << dbname;
        string connstr = o.str();
        ADODB::_RecordsetPtr pRst = NULL;
        ADODB::_ConnectionPtr pConnection = NULL;
        HRESULT hr = S_OK;
        try {
                hr = pConnection.CreateInstance(__uuidof(ADODB::Connection));
                if (FAILED(hr)) _com_issue_error(hr);
                hr = pConnection->Open(connstr.c_str(), "", "", ADODB::adConnectUnspecified);
                if (FAILED(hr)) _com_issue_error(hr);
                hr = pRst.CreateInstance(__uuidof(ADODB::Recordset));
                if (FAILED(hr)) _com_issue_error(hr);
                hr = pRst->QueryInterface(__uuidof(IADORecordBinding), (LPVOID*)&pIrb);
                if (FAILED(hr)) _com_issue_error(hr);

                hr = pRst->Open(tabname.c_str(), _variant_t((IDispatch *)pConnection, true),
                        ADODB::adOpenKeyset, ADODB::adLockOptimistic, ADODB::adCmdTable);
                if (FAILED(hr)) _com_issue_error(hr);

                //数据绑定
            hr = pIrb->BindToRecordset(&rs);
                for (auto x : data) {
                        rs.m_bh     = x.no;
                        wcscpy_s(rs.m_name,   30,x.name.c_str());
                        rs.m_sex    = x.sex;
                        rs.m_howold = x.howold;
                        rs.m_class  = x.classgroup;
                        wcscpy_s(rs.m_address,50,x.address.c_str());
                        rs.m_bhStatus      = 0;
                        rs.m_nameStatus    = 0;
                        rs.m_sexStatus     = 0;
                        rs.m_howoldStatus  = 0;
                        rs.m_classStatus   = 0;
                        rs.m_addressStatus = 0;
                        hr= pIrb->AddNew(&rs);
                        if (hr != S_OK) {
                            wcout.imbue(locale("chs"));
                                cout << "添加记录错误!记录重请检查数据" << endl;
                                cout << "记录域转换情况:" << endl;
                        cout <<   "状态:记录域 " << rs.m_bh      << (rs.m_bhStatus == adFldOK ?  "-- ok" :  "-- Null") << endl;
                                wcout << L"状态:记录域 " << rs.m_name    << (rs.m_bhStatus == adFldOK ? L"-- ok" : L"-- Null") << endl;
                                cout <<   "状态:记录域 " << rs.m_sex     << (rs.m_bhStatus == adFldOK ?  "-- ok" :  "-- Null") << endl;
                                cout <<   "状态:记录域 " << rs.m_howold  << (rs.m_bhStatus == adFldOK ?  "-- ok" :  "-- Null") << endl;
                                cout <<   "状态:记录域 " << rs.m_class   << (rs.m_bhStatus == adFldOK ?  "-- ok" :  "-- Null") << endl;
                                wcout << L"状态:记录域 " << rs.m_address << (rs.m_bhStatus == adFldOK ? L"-- ok" : L"-- Null") << endl;            
                        }
                        if (FAILED(hr)) _com_issue_error(hr);
                }

                //记录集直接增加,不过也很变态,要转几道才行
                //这里只弄一条
                _variant_t Fields[] = {
                        "编号",
                        "姓名",
                        "性别",
                        "年龄",
                        "班级",
                        "住址"
                };
                _variant_t Value[] = {
                        99,
                        L"班主任",
                        1,
                        24,
                        301,
                        L"城中村农家乐"
                };
                long len = sizeof Fields / sizeof Fields[0];
                //弄两个安全数组
                SAFEARRAYBOUND rgsaName[1], rgsaValue[1];  
                rgsaName[0].lLbound   = 0;   
                rgsaName[0].cElements = len;
                SAFEARRAY *psaName = SafeArrayCreate(VT_VARIANT, 1, rgsaName);
                rgsaValue[0].lLbound   = 0;  
                rgsaValue[0].cElements = len;
                SAFEARRAY *psaValue = SafeArrayCreate(VT_VARIANT, 1, rgsaValue);
                //把值传进去
                for (long i = 0;i < 6;i++)
                {
                        SafeArrayPutElement(psaName, &i, &Fields[ i ]);
                        SafeArrayPutElement(psaValue,&i, &Value[ i ]);
                }
                //再构成变量数组
                VARIANT vsaName, vsaValue;
                vsaName.vt = VT_VARIANT | VT_ARRAY;  
                vsaValue.vt = VT_VARIANT | VT_ARRAY;
                V_ARRAY(&vsaName)  = psaName;
                V_ARRAY(&vsaValue) = psaValue;
                //这样再给它用
                hr = pRst->AddNew(vsaName, vsaValue);
                if (hr != S_OK) {
                        cout << "添加记录 99 错误!可能记录重请检查数据" << endl;
                }
                if (FAILED(hr)) _com_issue_error(hr);
                cout << "数据添加完毕!" << endl;
                //下面是修改动作
                //修改后刷新获取的结果,不然pRst->GetRecordCount() 会不对。
                pRst->Requery(ADODB::adCmdUnknown);
                //合法移动范围 0- pRst->GetRecordCount() 之间,这里等于MoveLast;
                int pos = pRst->GetRecordCount();
                pRst->Move(pos-1);
                //if (pRst->Fields->GetItem("编号")->GetValue() ==variant_t(99))
                {
                        wcout.imbue(locale("chs"));
                        cout <<  "更改的当前记录:" << endl;
                        cout <<  "编号:"  << pRst->Fields->GetItem("编号")->GetValue().intVal  << endl;
                        wcout<< L"姓名:"  << pRst->Fields->GetItem("姓名")->GetValue().bstrVal << endl;
                        cout <<  "性别:"  << pRst->Fields->GetItem("性别")->GetValue().intVal  << endl;
                        cout <<  "年龄:"  << pRst->Fields->GetItem("年龄")->GetValue().intVal  << endl;
                        cout <<  "班级:"  << pRst->Fields->GetItem("班级")->GetValue().intVal  << endl;
                        wcout<< L"住址:"  << pRst->Fields->GetItem("住址")->GetValue().bstrVal << endl;
                        pRst->Fields->GetItem("编号")->Value = 88;
                        pRst->Fields->GetItem("姓名")->Value= L"女班主任";
                        pRst->Fields->GetItem("性别")->Value = 0;
                        pRst->Fields->GetItem("年龄")->Value = 54;
                        pRst->Fields->GetItem("班级")->Value = 301;
                        pRst->Fields->GetItem("住址")->Value = L"城中村农家乐";
                        pRst->Update();
                        //修改后刷新获取的结果
                        pRst->Requery(ADODB::adCmdUnknown);
                }
                pRst->Close();
                pConnection->Close();
        
        }
        catch (_com_error &e) {
                //错误号包含在 #include<oledberr.h>中
                cout << "异常返回码=0x" << hex<< e.Error() <<dec<< endl;
                _bstr_t bstrSource(e.Source());
                _bstr_t bstrDescription(e.Description());
                cout << "源  : " << (LPCSTR)bstrSource << endl;
                cout << "描述: " << (LPCSTR)bstrDescription << endl;
        }
        catch (...) {
                cout << "追加记录产生未知错误!...." << endl;
        }

        SAFE_RELEASE_P(pIrb);
        SAFE_RELEASE_O(pRst);
        SAFE_RELEASE_O(pConnection);
}
void showtable(string dbname,string tblname) {
        HRESULT hr = S_OK;
        stringstream o;
        o << "Provider = 'Microsoft.JET.OLEDB.4.0';Data source = " << dbname;
        string connstr = o.str();
        _bstr_t strcnn(connstr.c_str());
        _CatalogPtr pCatalog = NULL;
        ADODB::_RecordsetPtr pRecordset = NULL;
         try {
                hr = pRecordset.CreateInstance(__uuidof(ADODB::Recordset));
                if (FAILED(hr)) _com_issue_error(hr);
                hr = pCatalog.CreateInstance(__uuidof (Catalog));
                if (FAILED(hr)) _com_issue_error(hr);
                cout << "记录集\n=========" << endl;
                hr = pRecordset->Open(tblname.c_str(), strcnn, ADODB::adOpenKeyset, ADODB::adLockReadOnly, ADODB::adCmdTable);
                if (FAILED(hr))         _com_issue_error(hr);
                //保存关联连接
                pCatalog->PutActiveConnection(pRecordset->GetActiveConnection());
                if (pRecordset->RecordCount < 1) {
                        cout << "无记录行!" << endl;
                }
                //获取显示列名
                ADODB::FieldPtr pFld = NULL;
                cout << "[adox]";
                for (short Idx = 0; Idx < pRecordset->Fields->GetCount(); Idx++) {
                        pFld = pRecordset->Fields->GetItem(Idx);
                        cout << (LPCSTR)pFld->GetName();
                        switch (pFld->Type)
                        {
                        case adEmpty:cout << "(adEmpty)";break;
                        case adTinyInt:cout << "(adTinyInt)";break;
                        case adSmallInt:cout << "(adSmallInt)";break;
                        case adInteger:cout << "(adInteger)";break;
                        case adUnsignedTinyInt:cout << "(adUnsignedTinyInt)";break;
                        case adUnsignedSmallInt:cout << "(adUnsignedSmallInt)";break;
                        case adUnsignedInt:cout << "(adUnsignedInt)";break;
                        case adUnsignedBigInt:cout << "(adUnsignedBigInt)";break;
                        case adSingle:cout << "(adSingle)";break;
                        case adDouble:cout << "(adDouble)";break;
                        case adCurrency:cout << "(adCurrency)";break;
                        case adDecimal:cout << "(adDecimal)";break;
                        case adNumeric:cout << "(adNumeric)";break;
                        case adBoolean:cout << "(adBoolean)";break;
                        case adError:cout << "(adError)";break;
                        case adUserDefined:cout << "(adUserDefined)";break;
                        case adVariant:cout << "(adVariant)";break;
                        case adIDispatch:cout << "(adIDispatch)";break;
                        case adIUnknown:cout << "(adIUnknown)";break;
                        case adGUID:cout << "(adGUID)";break;
                        case adDate:cout << "(adDate)";break;
                        case adDBDate:cout << "(adDBDate)";break;
                        case adDBTime:cout << "(adDBTime)";break;
                        case adDBTimeStamp:cout << "(adDBTimeStamp)";break;
                        case adBSTR:cout << "(adBSTR)";break;
                        case adChar:cout << "(adChar)";break;
                        case adVarChar:cout << "(adVarChar)";break;
                        case adLongVarChar:cout << "(adLongVarChar)";break;
                        case adWChar:cout << "(adWChar)";break;
                        case adVarWChar:cout << "(adVarWChar)";break;
                        case adLongVarWChar:cout << "(adLongVarWChar)";break;
                        case adBinary:cout << "(adBinary)";break;
                        case adVarBinary:cout << "(adVarBinary)";break;
                        case adLongVarBinary:cout << "(adLongVarBinary)";break;
                        case adChapter:cout << "(adChapter)";break;
                        case adFileTime:cout << "(adFileTime)";break;
                        case adPropVariant:cout << "(adPropVariant)";break;
                        case adVarNumeric:cout << "(adVarNumeric)";break;
                        default:
                                cout << "(未知" << hex << pFld->Type << ")";
                        }
                        cout << "\t";
                }
                cout << endl;
                pRecordset->MoveFirst();
                int iCount = 0;
                while (!(pRecordset->EndOfFile)) {
                        cout << "\t";
                        for (long i = 0; i < pRecordset->Fields->GetCount(); ++i)
                        {
                                _variant_t FldVal = pRecordset->Fields->GetItem(i)->Value;
                                switch (FldVal.vt) {
                                case (VT_NULL):  cout << "NULL";break;
                                case (VT_BOOL):  cout << (FldVal.boolVal) ? "True " : "False";break;
                                case (VT_BSTR):  cout << (LPCSTR)(_bstr_t)FldVal.bstrVal;break;
                                case (VT_I1):    cout << (LPCSTR)(_bstr_t)FldVal.cVal;break;
                                case (VT_I2):    cout << (LPCSTR)(_bstr_t)FldVal.iVal;break;
                                case (VT_I4):    cout << (LPCSTR)(_bstr_t)FldVal.lVal;break;
                                case (VT_I8):    cout << (LPCSTR)(_bstr_t)FldVal.llVal;break;
                                case (VT_UI1):   cout << (LPCSTR)(_bstr_t)FldVal.bVal;break;
                                case (VT_UI2):   cout << (LPCSTR)(_bstr_t)FldVal.uiVal;break;
                                case (VT_UI4):   cout << (LPCSTR)(_bstr_t)FldVal.ulVal;break;
                                case (VT_UI8):   cout << (LPCSTR)(_bstr_t)FldVal.ullVal;break;
                                case (VT_INT):   cout << (LPCSTR)(_bstr_t)FldVal.intVal;break;
                                case (VT_UINT):  cout << (LPCSTR)(_bstr_t)FldVal.uintVal;break;
                                case (VT_EMPTY): cout << (LPCSTR)(_bstr_t)FldVal.lVal;break;
                                case (VT_R4):    cout << (LPCSTR)(_bstr_t)FldVal.fltVal;break;
                                case (VT_R8):    cout << (LPCSTR)(_bstr_t)FldVal.dblVal;break;
                                case (VT_LPWSTR):cout << (LPCSTR)(_bstr_t)FldVal.bstrVal;break;
                                //注意类型还有,这里只列举常用地。
                                default:cout << "  ";        break;
                                }
                                cout << "\t\t";
                        }
                        cout << endl;
                        pRecordset->MoveNext();
                }
        }
        catch (_com_error &e) {
                cout << "异常返回码=0x" << hex << e.Error() << dec << endl;
                _bstr_t bstrSource(e.Source());
                _bstr_t bstrDescription(e.Description());
                cout << "源     = " << (LPCSTR)bstrSource << endl;
                cout << "描述   = " << (LPCSTR)bstrDescription << endl;
        }
        catch (...) {
                cout << "流览记录集出错!." << endl;
        }
        SAFE_RELEASE_O(pCatalog);
        if (pRecordset)
        {
                if (pRecordset->State == 1)
                        pRecordset->Close();
                SAFE_RELEASE_O(pRecordset);
        }
}
int main()
{
        CoInitialize(NULL);
        string dbname = "demo.mdb";
        string tabname = "花名册";

        HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
        DWORD OldMode,NewMode;
        OldMode = GetConsoleMode(hStdin, &OldMode);
        NewMode = OldMode & ~ENABLE_LINE_INPUT;
        NewMode = NewMode | ENABLE_ECHO_INPUT;
        SetConsoleMode(hStdin, NewMode);
        char ch;
        while (1)
        {
                cout << "\n数据库demo.mdb存在,是否删除 Y/N/Q退出 ";
                cin.get(ch);
                int t = toupper(ch);
                if (t=='Q') return 0;
                if (t=='Y') {
                        DeleteFileA(dbname.c_str());
                        break;
                }
                if (t=='N')  break;
                Beep(660, 5);
        }
        cout << endl;
        SetConsoleMode(hStdin, OldMode);
        struct _stat64 stat;
        int FileExist = _stat64(dbname.c_str(), &stat);
        if (FileExist == -1) {
                cout << "建库..." << endl;
                bool b=createdatabase(dbname);
                if (!b) return -1;
                cout << "建表-花名册...." << endl;
                b=buildtable(dbname, tabname);
                if (!b) return -2;
                cout << "添加测试数据...." << endl;
                appenddata(dbname, tabname);
        }
        //显示
        showtable(dbname, tabname);
        system("pause");
        CoUninitialize();
    return 0;
}

运行结果:
数据库之本地数据库

注意:
数据库demo.mdb存在,是否删除 Y/N/Q退出 是为了处理异常,重复运行的情况
其中 Y 为删数据库重新建库,建表,添加数据,然后显示数据。
       N 为不删数据库,也不建表,添加数据。只显示。
       Q 为直接退出,什么都不做。
  
createdatabase,buildtable 不是通用,绑的死表。
showtable是通用地,自动判定,绑定数据库字段。


数据库之本地数据库

                                         xx_player           2019.5

不知道中途字体是怎么变歪地。多包涵。

评分

参与人数 1驿站币 +1 热心值 +1 收起 理由
16_avatar_small firefox + 1 + 1 膜拜大神,收藏学习!

查看全部评分





上一篇:现代C++的技巧-大浪淘金
下一篇:数据库之网络数据库
56_avatar_middle
最佳答案
0 
在线会员 发表于 2019-5-10 17:08:55 | 显示全部楼层
很厉害了,膜拜大神!!!!!!!!!!!!!!!!
81_avatar_middle
最佳答案
3 
online_supermod 发表于 2019-5-10 22:56:28 | 显示全部楼层
拜读一下,支持原创!
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-9-23 18:58

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表