当尝试使用 C 语言使用绑定(bind)参数插入多个记录时,我无法使用 char * str_data
使其工作,然后使用 strdup 的 malloc 设置“测试字符串”。我必须定义char str_data[50]
。如果我尝试使用 char * str_data 和 str_data = strdup("teststring") ,它会用随机字节填充 MySQL。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <my_global.h>
#include <mysql.h>
int main(void)
{
MYSQL *con;
con = mysql_init(NULL);
my_bool reconnect = 1;
mysql_options(con, MYSQL_OPT_RECONNECT, &reconnect);
if (mysql_real_connect(con, "127.0.0.1", "hidden", "hidden", "hidden", 0, NULL, 0) == NULL) {
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(0);
}
MYSQL_STMT *stmt;
MYSQL_BIND ps_params[1];
char str_data[50];
unsigned long str_length;
stmt = mysql_stmt_init(con);
mysql_stmt_prepare(stmt, "INSERT INTO `test` (two) VALUES (?)", strlen("INSERT INTO `test` (two) VALUES (?)"));
memset(ps_params, 0, sizeof(ps_params));
ps_params[0].buffer_type = MYSQL_TYPE_STRING;
ps_params[0].buffer = (char *)&str_data;
ps_params[0].buffer_length = 50;
ps_params[0].length = &str_length;
ps_params[0].is_null = 0;
mysql_stmt_bind_param(stmt, ps_params);
str_length = strlen("test string");
strcpy(str_data, "test string");
mysql_stmt_execute(stmt);
mysql_close(con);
}
有人可以向我解释为什么使用 char * str_data
和 str_data = strdup("teststring")
会导致 MySQL 读取乱码吗?
编辑:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <my_global.h>
#include <mysql.h>
int main(void)
{
MYSQL *con;
con = mysql_init(NULL);
my_bool reconnect = 1;
mysql_options(con, MYSQL_OPT_RECONNECT, &reconnect);
if (mysql_real_connect(con, "127.0.0.1", "hidden", "hidden", "hidden", 0, NULL, 0) == NULL) {
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(0);
}
MYSQL_STMT *stmt;
MYSQL_BIND ps_params[1];
char * str_data;
unsigned long str_length;
stmt = mysql_stmt_init(con);
mysql_stmt_prepare(stmt, "INSERT INTO `test` (two) VALUES (?)", strlen("INSERT INTO `test` (two) VALUES (?)"));
memset(ps_params, 0, sizeof(ps_params));
ps_params[0].buffer_type = MYSQL_TYPE_STRING;
ps_params[0].buffer = (char *)&str_data;
ps_params[0].buffer_length = (strlen("test string") + 1);
ps_params[0].length = &str_length;
ps_params[0].is_null = 0;
mysql_stmt_bind_param(stmt, ps_params);
str_length = strlen("test string");
str_data = strdup("test string");
mysql_stmt_execute(stmt);
mysql_close(con);
}
数据库结果:Ð|D =N_
结果为printf("'%s'\n", str_data)
:'测试字符串'
我认为这与 ps_params[0].buffer = (char *)&str_data;
作为指针有关
最佳答案
这是代码中令人反感的部分:
ps_params[0].buffer = (char *)&str_data;
.buffer
应该指向内存缓冲区,但它指向一个(未初始化的)指针。
事实上,您正在使用类型转换来消除编译器警告,这应该暗示出现了非常错误的情况。 在任何情况下都永远不要使用类型转换,除非您比编译器更了解发生了什么!
因此,如果str_data
指向缓冲区,只需使用str_data
的值初始化ps_params[0].buffer
code> 而不是 str_data
的地址。 .buffer
应该指向 str_data
指向的“同一事物”,而不是str_data
本身。像这样:
ps_params[0].buffer = str_data;
现在的问题是,您还没有初始化str_data
。它指向垃圾,所以现在 ps_params[0].buffer 也指向垃圾。因此,您必须将 str_data
的初始化移至 ps_params[0].buffer
的赋值之前:
char * str_data = strdup("test string");
unsigned long str_length = strlen(str_data);
stmt = mysql_stmt_init(con);
mysql_stmt_prepare(stmt, "INSERT INTO `test` (two) VALUES (?)", strlen("INSERT INTO `test` (two) VALUES (?)"));
memset(ps_params, 0, sizeof(ps_params));
ps_params[0].buffer_type = MYSQL_TYPE_STRING;
ps_params[0].buffer = str_data;
ps_params[0].buffer_length = str_len + 1;
ps_params[0].length = &str_length;
ps_params[0].is_null = 0;
mysql_stmt_bind_param(stmt, ps_params);
mysql_stmt_execute(stmt);
// `strdup` calls `malloc`, so we have to free the buffer after use
free(str_data);
mysql_close(con);
添加运行时错误检查作为读者的练习
关于c - 使用 mysql_stmt_prepare 时如何引用 char* 而不是使用 char[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56938848/