必须先调用mysql_init()初始化句柄,否则mysql_real_connect()会段错误或返回nullptr;字符集须在连接成功后立即调用mysql_set_character_set(conn,"utf8mb4")设置;取查询结果需判空row[i]并用mysql_fetch_lengths()获取长度。

用 mysql_real_connect() 连接 MySQL 之前必须初始化句柄
不调用 mysql_init() 或用 nullptr 直接传给 mysql_real_connect(),会导致段错误或返回 nullptr 且 mysql_error() 为空。这不是配置问题,是 C API 的硬性前提。
-
MYSQL *conn = mysql_init(nullptr);是安全写法,内部会做内存分配 - 如果传入已分配但未初始化的
MYSQL结构体指针,必须先调用mysql_options()或mysql_init()覆盖初始化 - 连接失败后别直接
mysql_close(conn)—— 如果conn是nullptr,会崩;应先判空
中文字段乱码?重点检查 mysql_set_character_set() 的调用时机
在 mysql_real_connect() 成功之后、执行任何 SQL 之前,必须立刻调用 mysql_set_character_set(conn, "utf8mb4")。只靠建表时指定 CHARSET=utf8mb4 或连接字符串加 ?charset=utf8mb4 不生效 —— C API 不解析 URL 参数。
- MySQL 8.0+ 默认字符集是
utf8mb4,但客户端连接层默认仍是latin1,不显式设置就会丢 emoji 和生僻汉字 - 不要用
"utf8"(MySQL 里这是阉割版,不支持四字节 UTF-8) - 执行
SET NAMES utf8mb4也能临时生效,但不如mysql_set_character_set()稳定,某些版本有竞态
查询结果怎么安全取字符串?别直接用 row[0]
MYSQL_ROW row = mysql_fetch_row(result) 返回的是 char **,其中元素可能是 nullptr(对应 SQL 的 NULL),也可能是有效地址。直接 printf("%s", row[0]) 会崩溃。
- 先用
mysql_fetch_lengths()拿长度,再配合row[i]判断是否为nullptr - 更稳妥:用
mysql_fetch_field()查字段类型,对MYSQL_TYPE_STRING/MYSQL_TYPE_VAR_STRING做空值分支 - 别把
row指针存起来复用 —— 下一次mysql_fetch_row()会覆盖内存
为什么 mysql_query() 成功了,但 mysql_store_result() 返回 nullptr?
这是 INSERT/UPDATE/DELETE 等非查询语句的正常现象。mysql_store_result() 只对 SELECT、SHOW、DESCRIBE 等返回结果集的语句有效。对修改类语句,该函数返回 nullptr,不代表出错。
立即学习“C++免费学习笔记(深入)”;
- 判断是否成功,看
mysql_query()返回值:0 表示成功,非 0 才要查mysql_error() - 想拿影响行数,用
mysql_affected_rows(conn),不是mysql_num_rows() - 如果误把 INSERT 当 SELECT 用
mysql_store_result()+mysql_fetch_row(),程序会因解引用nullptr崩溃
mysql_real_connect() 成功后的每一步都得手动判空、记错误、及时清理 —— 最容易漏的是字符集设置和结果集释放,一漏就是乱码或内存泄漏。











