使用C语言连接MySQL数据库_初级

本文详细介绍如何使用C语言将测试结果数据导入MySQL数据库,并执行增删改查操作。包括结构定义、读取数据、解析数据和SQL语句执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

* 1. 编译环境

* 操作系统 Ubuntu10.04
* GCC 4.4.3
* 首先请确保你的系统安装了下列软件包:
* 1. mysql-client,libmysqlclient-dev和libmysqlclient15off
* sudo apt-get install mysql-client libmysqlclient-dev libmysqlclient15off
*    ps:若提示找不到libmysqlclient15off,请在软件源中添加
*    deb http://security.ubuntu.com/ubuntu hardy-security main
* 2. mysql-server
* sudo apt-get install mysql-server
*

* 2. 使用前,先在mysql中建立数据库batman: create database batman;

* 在batman中建立两张表:TCPpackets, UDPpackets
* create table UDPpackets(MB double,KbperSec double,seconds double,percents double);
* create table TCPpackets(MB double,KbperSec double);
*

* 3. 编译选项:

* gcc -o c_mysql ./c_mysql.c -I /usr/include/mysql -L /usr/lib/mysql -l mysqlclient -std=c99
*

* 4. 使用方法:

* ./c_mysql <filename> -tcp|-udp

*/

源文件c_mysql.c的内容如下:

#if defined(_WIN32) || defined(_WIN64) //为了支持windows平台上的编译 #include <windows.h> #endif #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <mysql.h> //我的机器上该文件在/usr/include/mysql下 //定义数据库操作的宏,也可以不定义留着后面直接写进代码 #define INSERT_UDP "insert into UDPpackets values(%f,%f,%f,%f);" #define INSERT_TCP "insert into TCPpackets values(%f,%f);" //input file type #define TCP_DATA 1 #define UDP_DATA 2 typedef struct _UDPData { double MB; double KbperSec; double seconds; double percents; }UDPData, *pUDPData; typedef struct _TCPData { double MB; double KbperSec; }TCPData,*pTCPData; int readLine(FILE* fd, char* buf) { char c; c = fgetc(fd); while(c != '\n' && c != EOF) { *(buf++) = c; c = fgetc(fd); } *buf = '\0'; if(c == EOF) return EOF; else return 0; } void paresUDPRow(char* buf, pUDPData pudp) { int index = 0,strIndex = 0; char str[20]; char *model[] = {"sec","MBytes","Kbits/sec","("}; double dd[4]; for(int i=0; i<4; i++) { index = strstr(buf,model[i]) - buf; index += strlen(model[i]); while( buf[index] == ' ') index++; strIndex = 0; while( isdigit(buf[index]) || buf[index] == '.' ) { str[strIndex++] = buf[index++]; } str[strIndex] = 0; dd[i] = atof(str); } pudp->MB = dd[0]; pudp->KbperSec = dd[1]; pudp->seconds = dd[2]; pudp->percents = dd[3]; } void paresTCPRow(char* buf, pTCPData ptcp) { int index = 0,strIndex = 0; char str[20]; char *model[] = {"sec","MBytes"}; double dd[2]; for(int i=0; i<2; i++) { index = strstr(buf,model[i]) - buf; index += strlen(model[i]); while( buf[index] == ' ') index++; strIndex = 0; while( isdigit(buf[index]) || buf[index] == '.' ) { str[strIndex++] = buf[index++]; } str[strIndex] = 0; dd[i] = atof(str); } ptcp->MB = dd[0]; ptcp->KbperSec = dd[1]; } int main(int argc, char **argv) //char **argv 相当于 char *argv[] { MYSQL mysql,*sock; //定义数据库连接的句柄,它被用于几乎所有的MySQL函数 MYSQL_RES *res; //查询结果集,结构类型 char buf[256]; char qbuf[256]; //存放查询sql语句字符串 char * filename = NULL; int fileType = TCP_DATA; FILE* fudp; UDPData udp; TCPData tcp; if (argc != 3) { //检查输入参数 fprintf(stderr,"usage : ./c_mysql <filename> -tcp|-udp\n\n"); exit(1); } filename = argv[1]; if(strcmp(argv[2],"-tcp")!=0 && strcmp(argv[2],"-udp")!=0) { fprintf(stderr,"usage : ./c_mysql <filename> -tcp|-udp\n\n"); exit(EXIT_FAILURE); } fileType = !strcmp(argv[2],"-udp") ? UDP_DATA : TCP_DATA; mysql_init(&mysql); if (!(sock = mysql_real_connect(&mysql,"localhost","root","123456","batman",0,NULL,0))) { fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(&mysql)); perror(""); exit(1); } fudp = fopen(filename,"r"); if(fudp == NULL) { fprintf(stderr,"Couldn't open file %s\n\n",filename); exit(1); } while(readLine(fudp,buf) != EOF) { if(fileType == UDP_DATA) { paresUDPRow(buf,&udp); sprintf(qbuf, INSERT_UDP, udp.MB, udp.KbperSec, udp.seconds, udp.percents); } else { paresTCPRow(buf,&tcp); sprintf(qbuf,INSERT_TCP,tcp.MB,tcp.KbperSec); } fprintf(stdout,qbuf); fprintf(stdout,"\n"); res = mysql_query(sock,qbuf); if( res ) { fprintf(stderr,"Update failed (%s)\n",mysql_error(sock)); exit(1); } } mysql_close(sock); fclose(fudp); exit(0); return 0; //. 为了兼容大部分的编译器加入此行 }
上述代码的主要作用是把测试batman协议的结果数据保存到MySQL中,结果包括对TCP测试的结果和对UDP测试的结果。这两种数据的格式如下:
TCP:

[ 4] 0.0-24.9 sec 2.22 MBytes 747 Kbits/sec [ 5] 0.0-1576.9 sec 125 MBytes 665 Kbits/sec [ 4] 0.0-33.6 sec 2.00 MBytes 499 Kbits/sec [ 5] 0.0-11.9 sec 1.05 MBytes 735 Kbits/sec [ 4] 0.0-26.7 sec 1.98 MBytes 621 Kbits/sec [ 5] 0.0-23.1 sec 1.76 MBytes 638 Kbits/sec
UDP:

[ 3] 0.0-20.6 sec 2.08 MBytes 850 Kbits/sec 43.392 ms 36/ 1521 (2.4%) [ 4] 0.0-20.9 sec 2.13 MBytes 853 Kbits/sec 45.070 ms 0/ 1517 (0%) [ 3] 0.0-20.5 sec 1.80 MBytes 734 Kbits/sec 41.463 ms 9021/10302 (88%) [ 4] 0.0-20.9 sec 2.13 MBytes 855 Kbits/sec 41.880 ms 0/ 1517 (0%) [ 3] 0.0-20.6 sec 2.13 MBytes 869 Kbits/sec 12.608 ms 0/ 1521 (0%) [ 4] 0.0-20.8 sec 2.13 MBytes 857 Kbits/sec 41.295 ms 0/ 1517 (0%) [ 3] 0.0-733.7 sec 15.4 MBytes 176 Kbits/sec 359.811 ms 2913/13907 (21%) [ 4] 0.0-10.3 sec 1.00 MBytes 818 Kbits/sec 22.526 ms 0/ 713 (0%) [ 3] 0.0-34.1 sec 2.00 MBytes 493 Kbits/sec 3.466 ms 0/ 1427 (0%) [ 4] 0.0-12.2 sec 1.00 MBytes 688 Kbits/sec 84.498 ms 0/ 714 (0%)
这不是重点,重点是对MySQL的操作。可是废话已经一萝筐了...

1. 首先是第一个要用到的结构:

MYSQL

该结构代表1个数据库连接的句柄。几乎所有的MySQL函数均使用它。不应尝试拷贝MYSQL

结构。不保证这类拷贝结果会有用。在后续的数据库操作中都要把它作为参数的。

2. 在声明一个MYSQL类型的变量mysql后,就要首先调用 mysql_init(&mysql);

该函数的原型是:MYSQL *mysql_init(MYSQL *mysql)

描述

分配或初始化与mysql_real_connect()相适应的MYSQL对象。如果mysql是NULL指针,该

函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。如果

mysql_init()分配了新的对象,当调用mysql_close()来关闭连接时,将释放该对象。


返回值
初始化的MYSQL*句柄。如果无足够内存以分配新的对象,返回NULL。

错误
在内存不足的情况下,返回NULL。

3. 调用mysql_real_connect来获得一个连接实例。

该函数的原型是:MYSQL *mysql_real_connect(MYSQL *mysql,
const char *host,
const char *user,
const char *passwd,
const char *db,
unsigned int port,
const char *unix_socket,
unsigned long client_flag)

描述

mysql_real_connect()尝试与运行在主机上的MySQL数据库引擎建立连接。在你能够执行

需要有效MySQL连接句柄结构的任何其他API函数之前,mysql_real_connect()必须成功

完成。


参数的指定方式如下:
# 第1个参数应是已有MYSQL结构的地址。调用mysql_real_connect()之前,必须调用

mysql_init()来初始化MYSQL结构。

# “host”的值必须是主机名或IP地址。如果“host”是NULL或字符串"localhost",连接将被

视为与本地主机的连接。如果操作系统支持套接字(Unix)或命名管道(Windows),

将使用它们而不是TCP/IP连接到服务器。

# “user”参数包含用户的MySQL登录ID。如果“user”是NULL或空字符串"",用户将被视为

当前用户。在UNIX环境下,它是当前的登录名。在Windows ODBC下,必须明确指定

当前用户名。

# “passwd”参数包含用户的密码。如果“passwd”是NULL,仅会对该用户的(拥有1个空密

码字段的)用户表中的条目进行匹配检查。这样,数据库管理员就能按特定的方式设置

MySQL权限系统,根据用户是否拥有指定的密码,用户将获得不同的权限。


4. 执行增删改查操作mysql_query:

该函数的原型是:int mysql_query(MYSQL *mysql, const char *query)
描述

# 执行由“Null终结的字符串”查询指向的SQL查询。正常情况下,字符串必须包含1条SQL语

句,而且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含多条

由分号隔开的语句。

# mysql_query()不能用于包含二进制数据的查询,应使用mysql_real_query()取而代之

(二进制数据可能包含字符‘\0’,mysql_query()会将该字符解释为查询字符串结束)。

# 如果希望了解查询是否应返回结果集,可使用mysql_field_count()进行检查。

返回值
如果查询成功,返回0。如果出现错误,返回非0值。

总结:以上只是介绍了本程序要用到的MySQL数据结构和函数,这些介绍都是来自MySQL手册,

详细信息可以参MySQL C API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值