【C/C++学院】(23)Mysql数据库编程--C语言编程实现mysql客户端

【送给在路上的程序员】

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

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

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

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



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\n", mysql_error(&mysql));
        return -1;//连接失败,返回-1
    }

    printf("success connect to mysql\n");
    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\n", mysql_error(connection));
        return -1;//执行失败,返回-1
    }

    MYSQL_RES *result = mysql_store_result(connection);//得到查询结果
    if (result == (MYSQL_RES *) NULL)
    {
        printf("%s\n", 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\t", sqlField->name);//向屏幕打印字段名
            iFieldCount++;
        }
        printf("\n");//每一行结尾打印一个\n字符

        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\t");//如果值为NULL,屏幕打印为"NULL"
                else
                    printf("%s\t", (const char *)sqlRow[i]);//屏幕打印为字段内容
            }
            printf("\n");//每一行结尾打印一个\n字符
        }
        printf("query is ok, %u rows affected\n", (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\n", mysql_error(connection));
        return -1;
    }
    printf("query is ok, %u rows affected\n", (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\n", 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] = '\b';意思为把退格键修改为'\b'
    VERASE代表向前擦出一个字符,VINTR代表发送ctrl + C中断信号,ctrl + c的ASCII码为3
    例如:term.c_cc[VINTR] = '\t';意思为将tab键设置为终端信号
    tcsetattr中,第二个参数说明,TCSAFLUSH:发送了所有输出后更改才生效,在更改发生时,未读取的所有输入数据都被删除
    TCSANOW:更改立即生效
    TCSADRAIN:发送了所有输出后更改才发生,如果更改输出参数则应该使用该选项
    */
    term.c_cc[VERASE] = '\b';//'\b'为退格键的ASCII码
    if (tcsetattr(STDIN_FILENO, TCSANOW, &term) == -1)//设置系统termion
    {
        printf("tcsetattr error is %s\n", strerror(errno));
    }
    return;
}

void returnstty()//恢复系统的termios设置
{
    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &oldterm) == -1)//设置系统termion
    {
        printf("tcsetattr error is %s\n", 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语言的基础知识=====|

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

时间: 2024-12-01 23:07:16

【C/C++学院】(23)Mysql数据库编程--C语言编程实现mysql客户端的相关文章

JSP使用JDBC连接MYSQL数据库的方法_JSP编程

本文实例讲述了JSP使用JDBC连接MYSQL数据库的方法.分享给大家供大家参考,具体如下: 1. 可在 http://www.mysql.com/products/connector-j/index.html下载MySQL JDBC驱动程序mysql-connector-java-*.jar,如我下载的是mysql-connector-java-5.1.18-bin.jar并加入到ClassPath下面,或加入到项目中.   2. 注册JDBC驱动程序 try { Class.forName(

快速与MySQL交互,使用XMAPP打开MySQL数据库,并用shell进行与MySQL交互&lt;Window 10&gt;

1.如果想要通过XAMPP shell登录MySQL,还需要下载安装好XAMPP. 2.双击打开xampp-control.exe,会出现以下界面,点击开启Apache和MySQL,这样我们就开启服务了,之后我们可以通过图形界面或者DOS界面使用MySQL数据库,首先介绍DOS界面使用. a> 首先设置环境变量,在系统path值中加入";安装路径\xampp".这一步可以通过点击XMAPP的: 就可以立马获取\xampp的路径,然后设置环境变量. b> 打开xampp sh

MySQL数据库学习笔记(四)----MySQL聚合函数、控制流程函数(含navicat软件的介绍)

[正文] 一.navicat的引入:(第三方可视化的客户端,方便MySQL数据库的管理和维护) NavicatTM是一套快速.可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设.它的设计符合数据库管理员.开发人员及中小企业的需要.Navicat 是以直觉化的图形用户界面而建的,让你可以以安全并且简单的方式创建.组织.访问并共用信息. Navicat 是闻名世界.广受全球各大企业.政府机构.教育机构所信赖,更是各界从业员每天必备的工作伙伴,被公认为全球最受欢迎的MySQL前

MySQL数据库学习笔记(一)----MySQL 5.6.21的安装和配置(setup版)

[正文] [开发环境] 物理机版本:Win 7旗舰版(64位) MySQL版本:5.5.40MSI版(64位) 一.数据库类型: (1)关系数据库 (2)面向对象数据库 (3)XML数据库 现在的主流是关系型数据库.   二.数据库产品: 大型数据库有:Oracle.Sybase.DB2.SQL server 小型数据库有:MySQL.Access等 上面列举的数据库都是关系型数据库,只是Oracle中有一小部分是面向对象的.MySQL具有开源.免费等特性,适合中小型企业的开发.   三.关系型

mysql数据库备份设置延时备份方法(mysql主从配置)_Mysql

一 为什么需要延时备份percona-xtrabackup是一个优秀的用于增量备份的工具.今天我们讲到的延时备份也是使用他们的产品.以前在MySQL AB复制一文中提到了AB复制.我们首先回顾下MySQL复制的相关要点.AB复制又称主从复制,实现的是数据同步.经过以下步骤: 1)主服务器把数据更改记录到二进制日志中,这个操作叫做二进制日志事件: 2)从服务器把主服务器的二进制日志事件拷贝到自己的中继日志(relay log)中: 3)从服务器执行中继日志中的事件,把更改应用到自己的数据上. 在生

c语言编程-C语言编程,拜托了,各位大侠,求正解,!!!

问题描述 C语言编程,拜托了,各位大侠,求正解,!!! **** 编程模拟一物体沿斜面加速下滑并在水平面逐渐减速(如图3所示)的物理过程.并给出各个图标的内容或设置. ****

c语言编程-C语言编程,关于方程组求解

问题描述 C语言编程,关于方程组求解 要求一个任意大小的方程组(Ax=b,A为任意大小的方阵)采用C/C++求特定方程组(系数矩阵维数大于10*10) 解决方案 http://www.jb51.net/article/43418.htmhttp://blog.csdn.net/zhangchao3322218/article/details/7412686http://wenku.baidu.com/link?url=7FR4ZbZi9vtdM8ESka2_G5XiW063Y-jGrhs_zDL

c语言编程-C语言编程问题,求大神帮助

问题描述 C语言编程问题,求大神帮助 斐波那契数列An,定义fn=An/An-1,要求当fn-fn-1<0.001时,输出此时的fn和n,用c语言实现,,求程序 解决方案 首项和第二项有给出是多少吗?

MySQL数据库学习笔记(二)----MySQL数据类型

[正文] 上一章节中,我们学习了MySQL软件的安装,既然软件都装好了,现在就正式开始MySQL的基础知识的学习吧,即使是零基础,也要一步一个脚印.恩,首先要学习的就是MySQL的数据类型. 一.数据类型: 1.整型(xxxint) 2.浮点型(float和double) 3.定点数(decimal) 4.字符串(char,varchar,xxxtext) 5.二进制数据(xxxBlob) 6.日期时间类型   二.数据类型介绍: 1.整型: 注:M表示最大的显示宽度.其中,int用的最多. 2