zoukankan      html  css  js  c++  java
  • 【C/C++学院】(23)Mysql数据库编程--C语言编程实现mysqlclient


    【送给在路上的程序猿】

    对于一个开发人员而言,能够胜任系统中随意一个模块的开发是其核心价值的体现。



    对于一个架构师而言,掌握各种语言的优势并能够利运用到系统中,由此简化系统的开发,是其架构生涯的第一步。



    对于一个开发团队而言。能够在短期内开发出用户惬意的软件系统是其核心竞争力的体现。

    每个程序猿都不能固步自封,要多接触新的行业,新的技术领域,突破自我。


    makefile

    .SUFFIXES: .c .o
    
    CC=gcc
    SRCS=mysql1.c
                mydb.c
    
    OBJS=$(SRCS:.c=.o)
    EXEC=mysql1
    
    all: $(OBJS)
        $(CC) -o $(EXEC) $(OBJS) -lmysqlclient
        @echo '-------------ok--------------'
    
    .c.o:
        $(CC) -Wall -g -o $@ -c $< 
    
    clean:
        rm -f $(OBJS)
        rm -f core*
    

    mydb.h

    #ifndef MYDB_H_
    #define MYDB_H_
    
    
    void init_db();
    int conn_db(const char *hostname, const char *username, const char *password,
            const char *dbname);
    void disconn_db();
    int open_db(const char *SQL);
    int exec_db(const char *SQL);
    
    #endif /* MYDB_H_ */

    mydb.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <mysql/mysql.h>
    #include "mydb.h"
    
    MYSQL *connection = NULL;
    MYSQL mysql;
    
    void init_db()
    {
        mysql_init(&mysql);//初始化mysql
    }
    
    int conn_db(const char *hostname, const char *username, const char *password,
            const char *dbname)
    {
        if (connection)
            mysql_close(connection);
        connection = mysql_real_connect(&mysql, hostname, username, password,
                dbname, 0, 0, 0);//连接到mysql
    
        if (connection == NULL)
        {
            printf("%s
    ", mysql_error(&mysql));
            return -1;//连接失败,返回-1
        }
    
        printf("success connect to mysql
    ");
        return 0;
    }
    
    void disconn_db()//断开数据库连接
    {
        if (connection)
        {
            mysql_close(connection);
            connection = NULL;
        }
    }
    
    int open_db(const char *SQL)//运行有返回数据集的SQL语句
    {
        int state = mysql_query(connection, SQL);//运行SQL语句
        if (state != 0)
        {
            printf("%s
    ", mysql_error(connection));
            return -1;//运行失败,返回-1
        }
    
        MYSQL_RES *result = mysql_store_result(connection);//得到查询结果
        if (result == (MYSQL_RES *) NULL)
        {
            printf("%s
    ", mysql_error(connection));
            return -1;//运行失败。返回-1
        } else
        {
            MYSQL_FIELD *sqlField;
            int iFieldCount = 0;
            while (1)//循环遍历全部字段
            {
                sqlField = mysql_fetch_field(result);
                if (sqlField == NULL)
                    break;
                printf("%s	", sqlField->name);//向屏幕打印字段名
                iFieldCount++;
            }
            printf("
    ");//每一行结尾打印一个
    字符
    
            MYSQL_ROW sqlRow;
            while (1)//循环到每一行
            {
                sqlRow = mysql_fetch_row(result);
                if (sqlRow == NULL)
                    break;
                int i;
                for (i = 0; i < iFieldCount; i++)//循环得到每一行中的每个字段
                {
                    if (sqlRow[i] == NULL)
                        printf("NULL	");//假设值为NULL。屏幕打印为"NULL"
                    else
                        printf("%s	", (const char *)sqlRow[i]);//屏幕打印为字段内容
                }
                printf("
    ");//每一行结尾打印一个
    字符
            }
            printf("query is ok, %u rows affected
    ", (unsigned int)mysql_affected_rows(connection));
            mysql_free_result(result);
        }
        return 0;
    }
    
    int exec_db(const char *SQL)//运行没有返回数据集的SQL语句
    {
        int state = mysql_query(connection, SQL);//运行SQL语句
        if (state != 0)
        {
            printf("%s
    ", mysql_error(connection));
            return -1;
        }
        printf("query is ok, %u rows affected
    ", (unsigned int)mysql_affected_rows(connection));
        return 0;
    }

    mysql1.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <errno.h>
    #include <termios.h>
    #include "mydb.h"
    
    
    void sqldb(const char *src)//參数src为要运行的SQL语句
    {
        if ((strncmp(src, "select", 6) == 0) || (strncmp(src, "SELECT", 6) == 0)
                || (strncmp(src, "show", 4) == 0) || (strncmp(src, "SHOW", 4) == 0)
                || (strncmp(src, "desc", 4) == 0) || (strncmp(src, "DESC", 4) == 0))
        {
            open_db(src);//假设src为有返回数据集SQL语句,那么调用open_db函数
        } else
        {
            exec_db(src);//假设src为没有有返回数据集SQL语句。那么调用exec_db函数
        }
    }
    
    
    
    void work(const char *userid, const char *password)
    {
        init_db();
        if (conn_db("localhost", userid, password, "test") != 0)//连接到数据库
        {
            return;//连接数据库失败。函数退出
        }
        char buf[2048];
        while (1)//循环从键盘读取
        {
            write(STDOUT_FILENO, "mysql1>", strlen("mysql1>"));//屏幕输出命令提示符mysql1>
            memset(buf, 0, sizeof(buf));
            read(STDIN_FILENO, buf, sizeof(buf));//等待用户从键盘输入
            if (strncmp(buf, "quit", 4) == 0)
                break;//用户输入quit,循环break;
            sqldb(buf);
        }
        disconn_db();//断开数据库连接
    }
    
    
    struct termios oldterm;
    void setstty()//设置输入退格键,不回显
    {
        //system("stty erase ^H");//运行shell命令,也能够 用来设置读取用户键盘输入的时候。退格键不回显
        struct termios term;
        if(tcgetattr(STDIN_FILENO, &term) == -1)//得到系统termion的设置
        {
            printf("tcgetattr error is %s
    ", strerror(errno));
            return;
        }
    
        oldterm = term;//保留当前termios设置,以便程序退出的时候能够恢复termios
    
        /*
        term.c_lflag &= ~ICANON;//取消ICANON选项(不规范输入)
        term.c_lflag |= ICANON;//设置ICANON选项(规范输入)
        term.c_cc字段为要设置的详细特殊输入字符,如c_cc[VERASE]代表退格键,
        term.c_cc[VERASE] = '';意思为把退格键改动为''
        VERASE代表向前擦出一个字符,VINTR代表发送ctrl + C中断信号,ctrl + c的ASCII码为3
        比如:term.c_cc[VINTR] = '	';意思为将tab键设置为终端信号
        tcsetattr中,第二个參数说明,TCSAFLUSH:发送了全部输出后更改才生效。在更改发生时,未读取的全部输入数据都被删除
        TCSANOW:更改马上生效
        TCSADRAIN:发送了全部输出后更改才发生。假设更改输出參数则应该使用该选项
        */
        term.c_cc[VERASE] = '';//''为退格键的ASCII码
        if (tcsetattr(STDIN_FILENO, TCSANOW, &term) == -1)//设置系统termion
        {
            printf("tcsetattr error is %s
    ", strerror(errno));
        }
        return;
    }
    
    void returnstty()//恢复系统的termios设置
    {
        if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &oldterm) == -1)//设置系统termion
        {
            printf("tcsetattr error is %s
    ", strerror(errno));
        }
        return;
    }
    
    
    int main(int arg, char *args[])
    {
        if (arg < 4)//假设没有參数,main函数退出
        {
            return EXIT_FAILURE;
        }
    
        if (strncmp(args[1], "-u", 2) != 0)//假设第二个參数不是-u。main函数退出
        {
            return EXIT_FAILURE;
        }
    
        if (strncmp(args[3], "-p", 2) != 0)//假设第四个參数不是-p,main函数退出
        {
            return EXIT_FAILURE;
        }
    
        const char *passwd = getpass("please input password:");//输入密码,屏幕不回显
    
        setstty();//设置输入退格键,不回显
        work(args[2], passwd);
        returnstty();//恢复系统的termios设置
        return EXIT_SUCCESS;
    }


    |========== 吴英强CSDN博客专栏==========|

    |== C/C++学院 专栏文章的内容(不定期更新)===|

    |== linux驱动开发 探索linux底层的奥秘 ========|

    |== Java基础学习篇 掌握java语言的基础知识=====|

    |====== 每天进步一点点,健康快乐每一天 ======|

  • 相关阅读:
    PAT (Advanced Level) 1010. Radix (25)
    PAT (Advanced Level) 1009. Product of Polynomials (25)
    PAT (Advanced Level) 1008. Elevator (20)
    PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
    PAT (Advanced Level) 1006. Sign In and Sign Out (25)
    PAT (Advanced Level) 1005. Spell It Right (20)
    PAT (Advanced Level) 1004. Counting Leaves (30)
    PAT (Advanced Level) 1001. A+B Format (20)
    PAT (Advanced Level) 1002. A+B for Polynomials (25)
    PAT (Advanced Level) 1003. Emergency (25)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5078268.html
Copyright © 2011-2022 走看看