美文网首页程序员
用VC++6.0和sqlite3数据库做个通讯录

用VC++6.0和sqlite3数据库做个通讯录

作者: kevin_captain | 来源:发表于2017-12-21 18:28 被阅读389次

    首先,我是很反感使用vc++6.0的,但是呢,我国的大学生计算机方面的基础教学是永远跟不上“潮流”的,考虑到接下来的五六年里还是会有部分高校的同学仍旧会被老师要求用VC++6.0做课程设计,为了让你们也少走一些坑,所以写个笔记吧(装作认真的样子)

    我在哔哩哔哩上传一个自己做的MFC版的通讯录视频教程,大家感兴趣的可以去看看http://www.bilibili.com/video/av17669542?share_medium=android&share_source=copy_link&bbid=266B7E4B-B6FC-42AB-972E-95F8A6C25BDD23663infoc&ts=1516379988138

    1. 让你的VC++ 6.0支持sqlite3

    首先,先把这三个文件下载好:https://pan.baidu.com/s/1micNdgO
    分别是
    sqlite3.h
    sqlite3.lib
    sqlite3.dll

    这三个文件我是怎么得来的呢?如果你想知道的话就看下这一段吧:
    sqlite3.h : 打开 http://www.sqlite.org/download.html ,下载源码文件然后解压,可以看到sqlite3.h这个文件(如果你想自己编译的话也可以自行编译成lib或者dll)

    image.png
    sqlite3.lib : 还是在上面那个官网下载地址,我下载的是32位的文件,解压之后你会看到sqlite3.dll和sqlite3.def两个文件
    image.png
    sqlite3.lib: 记得将你的vc++6.0的安装地址如 C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin 加入到系统的环境变量里面去,因为待会我们需要用到这个目录下的lib.exe程序,记得解压出来的sqlite3.def文件吗?打开命令行窗口(Win+R)并且进入该文件当前目录,然后输入指令 lib /def:sqlite3.def 就会在当前目录生成一个sqlite.lib文件
    image.png

    接下来就是配置VC++6.0了

    将sqlite3.h添加到目录 C:\Program Files (x86)\Microsoft Visual Studio\VC98\Include下
    (根据你自己的VC++6.0安装目录添加啊,你的安装目录不一定跟我的一样)

    将sqlite3.lib添加到目录C:\Program Files (x86)\Microsoft Visual Studio\VC98\Iib下
    为了保证可以运行,你还需要将sqlite3.dll加入到系统环境里面去,如果是32位电脑将sqlite3.dll添加到 C:\Windows\System32 如果是64位加入到C:\Windows\SysWOW64

    如果你要把你做好的exe文件拷贝给别人使用,记得在这个exe文件同目录下添加sqlite3.dll这个动态链接库,但如果你是静态编译的话就不需要拷贝这个dll文件了

    ok ,现在你的VC++ 6.0是可以使用sqlite数据库的库文件了。
    你需要使用sqlite的话,下面这两句是必须的:

    #include "sqlite3.h"
    #pragma comment(lib,"sqlite3.lib")
    

    2. 做一个基于控制台的通讯录

    首先,你可以使用sqlite的一些工具先生成一个数据库test.db(对应main函数里的controller类声明的参数test.db),表名是telbook,其中,数据表的结构如下:

    CREATE TABLE "main"."telbook" (
    "id"  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    "name"  TEXT NOT NULL,
    "telphone"  TEXT NOT NULL,
    "email"  TEXT,
    "type"  TEXT,
    "remark"  TEXT
    );
    

    偷懒直接把代码贴上来啦:
    控制数据库的类的头文件controller.h

    #include <iostream>
    #include <string>
    #include "sqlite3.h"
    using namespace std;
    
    #pragma comment(lib,"sqlite3.lib")
    
    class SqlController
    {
    public:
        sqlite3 *db;
        string table;
        string dbname;
    
        SqlController(string c_dbname,string c_tablename)
        {
            table = c_tablename;
            dbname = c_dbname;
        }
    
        
        //增加数据,成功返回1
        int addData(string name,string telphone,string email,string type,string remark);
        //根据手机号查询数据, 根据表的结构,如果有数据那么有两行,有6列,返回的值是个一维字符串数组,re[0 - 5]是字段
        char ** getInfoByTel(string telphone);
        //根据id获得信息
        char ** getInfoById(int id);
        //获取全部数据
        char ** getAll(int &row);
        //修改一条信息,成功返回1
        int changeData(int id,string name,string telphone,string email,string type,string remark);
        //删除一条信息,成功返回1
        int deleteData(int id);
    };
    

    实现该类函数的源文件controller.cpp

    #include "controller.h"
    #include <sstream>
    
    //增加数据
    int SqlController::addData(string name,string telphone,string email,string type,string remark)
    {
        int rc;
        const char *sql;
        char *zErrMsg;
        string s;
        //判断数据库是否存在
        rc = sqlite3_open(dbname.data(),&db);
        if( rc ){       //数据库不存在
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return 0;
        }else{      //数据库存在
            fprintf(stderr, "Opened database successfully\n");
            //判断是否已经存在该手机号
            char ** pResult;
            int nRow,nCol;
            s = "SELECT * FROM '"+table+"' WHERE telphone= '"+telphone+"';";
            sql = s.data();
            rc = sqlite3_get_table(db, sql, &pResult, &nRow, &nCol, NULL);
            if ( rc == SQLITE_OK )
            {
                if ( nRow >= 1)
                    return 2;       //表示该手机号已被登记
            }
            sqlite3_free_table(pResult);
            // 尝试插入数据
            s = "INSERT INTO '"+table+"' (NAME,TELPHONE,EMAIL,TYPE,REMARK) VALUES ('"+\
                name+"','"+telphone+"','"+email+"','"+type+"','"+remark+"' );";
            sql = s.data();
            cout<<sql<<endl;
            // 开始插入数据
            rc = sqlite3_exec(db, sql, NULL, NULL, &zErrMsg);
            if( rc != SQLITE_OK ){  //如果不成功
                fprintf(stderr, "SQL error: %s\n", zErrMsg);
                sqlite3_free(zErrMsg);
                return 0;
            }else{      // 成功
                fprintf(stdout, "AddData successfully\n");
            }
        }
        sqlite3_close(db);
        return 1;
    }
    
    //修改数据
    int SqlController::changeData(int id,string name,string telphone,string email,string type,string remark)
    {
        int rc;
        const char *sql;
        char *zErrMsg;
        string s,str;
        stringstream ss;
        ss<<id;
        ss>>str;
        //判断数据库是否存在
        rc = sqlite3_open(dbname.data(),&db);
        if( rc ){       //数据库不存在
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return 0;
        }else{      //数据库存在
            fprintf(stderr, "Opened database successfully\n");
            s = "UPDATE '"+table+"' SET name='"+name+"',telphone='"+telphone+"', email ='"+email+"',type = '"+type+"',remark = '"+remark+"'  WHERE id = " +str+";"; 
            sql = s.data();
            cout<<sql<<endl;
            // 开始插入数据
            rc = sqlite3_exec(db, sql, NULL, NULL, &zErrMsg);
            if( rc != SQLITE_OK ){  //如果不成功
                fprintf(stderr, "SQL error: %s\n", zErrMsg);
                sqlite3_free(zErrMsg);
                return 0;
            }else{      // 成功
                fprintf(stdout, "ChangeData successfully\n");
            }
        }
        sqlite3_close(db);
        return 1;
    }
    
    //删除数据
    int SqlController::deleteData(int id)
    {
        int rc;
        const char *sql;
        char *zErrMsg;
        string s,str;
        stringstream ss;
        ss<<id;
        ss>>str;
        //判断数据库是否存在
        rc = sqlite3_open(dbname.data(),&db);
        if( rc ){       //数据库不存在
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return 0;
        }else{      //数据库存在
            fprintf(stderr, "Opened database successfully\n");
            //判断是否已经存在该手机号
            char ** pResult;
            int nRow,nCol;
            s = "SELECT * FROM '"+table+"' WHERE id= '"+str+"';";
            sql = s.data();
            rc = sqlite3_get_table(db, sql, &pResult, &nRow, &nCol, NULL);
            if ( rc == SQLITE_OK )
            {
                if ( nRow < 1)
                    return 2;       //表示该id不存在
            }
            sqlite3_free_table(pResult);
            s = "DELETE FROM '"+table+"'  WHERE id = " +str+";";    
            sql = s.data();
            cout<<sql<<endl;
            // 开始删除数据
            rc = sqlite3_exec(db, sql, NULL, NULL, &zErrMsg);
            if( rc != SQLITE_OK ){  //如果不成功
                fprintf(stderr, "SQL error: %s\n", zErrMsg);
                sqlite3_free(zErrMsg);
                return 0;
            }else{      // 成功
                fprintf(stdout, "DeleteData successfully\n");
            }
        }
        sqlite3_close(db);
        return 1;
    }
    
    //根据手机号精确查找,返回数组的第一个值为no表示手机号不存在,返回error表示数据库错误
    char** SqlController::getInfoByTel(string telphone)
    {
        int rc , nRow, nCol;
        const char *sql;
        char** pResult;
        char* pErr[] = {"error"};           //char* a [] 等价于 char **, 是一个char的指针数组
        char* pNoTel[] = {"no"};
        char *zErrMsg;
        string s;
        //判断数据库是否存在
        rc = sqlite3_open(dbname.data(),&db);
        if( rc ){       //数据库不存在
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return pErr;
        }else{      //数据库存在
            fprintf(stderr, "Opened database successfully\n");
            
            //开始查找该手机号
            s = "SELECT * FROM '"+table+"'  WHERE telphone = '" +telphone+"';"; 
            sql = s.data();
            cout<<sql<<endl;
            rc = sqlite3_get_table(db, sql, &pResult, &nRow, &nCol, &zErrMsg);
            if( rc != SQLITE_OK ){  //如果不成功
                fprintf(stderr, "SQL error: %s\n", zErrMsg);
                return pErr;
            }else{      // 成功
                fprintf(stdout, "Select Info With Tel successfully\n");
                if ( nRow < 1 )   //该手机号信息不存在
                    return pNoTel; 
                else{
                    return pResult;
                }
            }
            sqlite3_free_table(pResult);
        }
        sqlite3_close(db);
        return pErr;
    }
    
    char ** SqlController::getInfoById(int id)
    {
        int rc , nRow, nCol;
        const char *sql;
        char** pResult;
        char* pErr[] = {"error"};           //char* a [] 等价于 char **, 是一个char的指针数组
        char* pNo[] = {"no"};
        char *zErrMsg;
        string s,str;
        stringstream ss;
        ss<<id;
        ss>>str;
        //判断数据库是否存在
        rc = sqlite3_open(dbname.data(),&db);
        if( rc ){       //数据库不存在
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return pErr;
        }else{      //数据库存在
            fprintf(stderr, "Opened database successfully\n");
            //开始查找该id
            s = "SELECT * FROM '"+table+"'  WHERE id = " +str+";";  
            sql = s.data();
            cout<<sql<<endl;
            rc = sqlite3_get_table(db, sql, &pResult, &nRow, &nCol, &zErrMsg);
            if( rc != SQLITE_OK ){  //如果不成功
                fprintf(stderr, "SQL error: %s\n", zErrMsg);
                return pErr;
            }else{      // 成功
                fprintf(stdout, "Select Info With Tel successfully\n");
                if ( nRow < 1 )   //该id信息不存在
                    return pNo; 
                else{
                    return pResult;
                }
            }
            sqlite3_free_table(pResult);
        }
        sqlite3_close(db);
        return pErr;
    }
    
    char ** SqlController::getAll(int &row)
    {
        int rc , nRow, nCol;
        const char *sql;
        char** pResult;
        char* pErr[] = {"error"};           //char* a [] 等价于 char **, 是一个char的指针数组
        char* pNo[] = {"no"};
        char *zErrMsg;
        string s;
        //判断数据库是否存在
        rc = sqlite3_open(dbname.data(),&db);
        if( rc ){       //数据库不存在
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return pErr;
        }else{      //数据库存在
            fprintf(stderr, "Opened database successfully\n");      
            //开始查询数据
            s = "SELECT * FROM '"+table+"';";   
            sql = s.data();
            cout<<sql<<endl;
            rc = sqlite3_get_table(db, sql, &pResult, &nRow, &nCol, &zErrMsg);
            if( rc != SQLITE_OK ){  //如果不成功
                fprintf(stderr, "SQL error: %s\n", zErrMsg);
                return pErr;
            }else{      // 成功
                fprintf(stdout, "Select Info With Tel successfully\n");
                if ( nRow < 1 )   //没有任何信息
                    return pNo; 
                else{
                    row = nRow;     //返回行数,那么一共有6*row个元素
                    return pResult;
                }
            }
            sqlite3_free_table(pResult);
        }
        sqlite3_close(db);
        return pErr;
    }
    

    主程序的源代码文件 main.cpp

    #include "controller.h"
    #include <stdlib.h>
    
    void menu();
    
    int main()
    {
        int index,i,j;
        char  is;
        int re , id , row;
        char ** reList;
        SqlController *sq =new  SqlController("test.db","telbook");
        string name,telphone,email,type,remark;
        //弹出菜单
        menu();
        cout<<"请输入您的选项:";cin>>index;
        while(1)
        {
            switch (index)
            {
            case 0:
                cout<<"确认退出吗?(Y/N)  :";
                cin>>is;
                if ( is == 'Y' || is == 'y' )
                    return 0;
                break;
            case 1:
                cout<<"请输入姓名:";
                cin>>name;
                cout<<"请输入手机:";
                cin>>telphone;
                cout<<"请输入邮箱:";
                cin>>email;
                cout<<"请输入类别:";
                cin>>type;
                cout<<"请输入备注:";
                cin>>remark;
                re = sq->addData(name,telphone,email,type,remark);
                if ( re == 2 )
                    cout<<"ERROR! 该手机号已经被录入,不能重新录入!"<<endl;
                else if ( re == 0)
                    cout<<"ERROR! 出现未知错误,数据库错误!"<<endl;
                else 
                    cout<<"添加信息成功!"<<endl;
                break;
            case 2:
                cout<<"请输入手机:";
                cin>>telphone;
                reList = sq->getInfoByTel(telphone);
                if (reList[0] == "no")
                {
                    cout<<"该手机号信息不存在!"<<endl;
                    break;
                }
                if (reList[0] == "error")
                {
                    cout<<"数据库发生错误!"<<endl;
                    break;
                }
                for (i=0, j=0; i<12; i++ )
                {
                    cout<<reList[i]<<"\t";
                    if ( j == 5 )
                    {
                        j = 0;
                        cout<<endl;
                    }
                    else
                        j ++;
                }
                break;
            case 3:
                cout<<"请输入您要修改的信息的id号:";
                cin>>id;
                cout<<"请输入姓名:";
                cin>>name;
                cout<<"请输入手机:";
                cin>>telphone;
                cout<<"请输入邮箱:";
                cin>>email;
                cout<<"请输入类别:";
                cin>>type;
                cout<<"请输入备注:";
                cin>>remark;
                re = sq->changeData(1,name,telphone,email,type,remark);
                if ( re==0 )
                    cout<<"ERROR!数据库发生错误!"<<endl;
                else
                    cout<<"修改成功!"<<endl;
                break;
            case 4:
                cout<<"请输入您要删除的信息的id号:";
                cin>>id;
                cout<<"您确认要删除这条信息吗?一旦删除不可以恢复!(Y/N) : ";
                cin>>is;
                if ( is == 'Y' || is == 'y' )
                {
                    re = sq->deleteData(id);
                    if ( re==0 )
                        cout<<"ERROR!数据库发生错误!"<<endl;
                    else
                        cout<<"删除成功!"<<endl;
                }
                else
                    cout<<"您已取消删除操作!"<<endl;
                break;
            case 5:
                reList = sq->getAll(row);
                for (i=0, j=0; i<6*row; i++ )
                {
                    cout<<reList[i]<<"\t";
                    if ( j == 5 )
                    {
                        j = 0;
                        cout<<endl;
                    }
                    else
                        j ++;
                }
                break;
            case 6:
                system("cls");
                menu();
                break;
            }
            cout<<"请输入您的选项:";cin>>index;
        }
    }
    
    void menu()
    {
        cout<<"******通讯录菜单*****"<<endl;
        cout<<"*  1. 录入一条通讯信息"<<endl;
        cout<<"*  2. 通过手机号查询信息"<<endl;
        cout<<"*  3. 修改一条信息"<<endl;
        cout<<"*  4. 删除一条信息"<<endl;
        cout<<"*  5. 查看全部通讯录信息"<<endl;
        cout<<"*  6. 清屏并且弹出菜单"<<endl;
        cout<<"*  0. 退出"<<endl;
    }
    

    说点废话,为什么使用sqlite3这个数据库?因为方便,给老师看的话带上这个文件就行了,老师也可以直接打开。如果我用MySQL,那岂不是老师检查还得安装MySQL环境?如果你说还有SQL Server?我觉得这个臃肿的胖子有点嘻哈#_#。用远程服务器的MYSQL?还是太麻烦了,所以SQLite夺冠

    本文(完)

    相关文章

      网友评论

        本文标题:用VC++6.0和sqlite3数据库做个通讯录

        本文链接:https://www.haomeiwen.com/subject/bqnawxtx.html