在 C/C++ 中使用 MySQL C API 連接數據庫時,正確設置字符集至關重要,否則會導致中文亂碼、mysql_real_escape_string 轉義錯誤等問題。本文總結三種主流方法,對比優缺點並給出推薦方案。
mysql_set_character_set() —— 推薦首選[cpp]
MYSQL *mysql = mysql_init(NULL);
mysql_real_connect(mysql, "host", "user", "pass", "db", 3306, NULL, 0);
// 設置連接字符集為 utf8(或 utf8mb4)
if (mysql_set_character_set(mysql, "utf8mb4")) {
fprintf(stderr, "設置字符集失敗: %s\n", mysql_error(mysql));
}
mysql_real_escape_string(),確保轉義使用正確字符集。MYSQL_OPT_RECONNECT)後保持字符集設置。需 MySQL 5.0.5 或更高版本。
SET NAMES[cpp]
const char *sql = "SET NAMES utf8mb4";
mysql_real_query(mysql, sql, (unsigned long)strlen(sql));
mysql_real_escape_string() 的行為,可能導致安全漏洞(如 SQL 注入)。mysql_options() 設置 MYSQL_SET_CHARSET_NAME[cpp]
// 必須在 mysql_real_connect() 之前調用!
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4");
mysql_real_connect(mysql, ...);
mysql_real_escape_string()。mysql_real_connect() 之前調用,否則無效。| 特性 | mysql_set_character_set | SET NAMES SQL | mysql_options |
|---|---|---|---|
| 影響 mysql_real_escape_string | ✅ 是 | ❌ 否 | ❌ 否 |
| 自動重連後保持 | ✅ 是 | ❌ 否 | ✅ 是 |
| 最低版本要求 | 5.0.5+ | 所有版本 | 所有版本 |
| 調用時機 | 連接後 | 連接後 | 連接前 |
mysql_set_character_set(mysql, "utf8mb4"),並在連接屬性中開啟自動重連:mysql_options(mysql, MYSQL_OPT_RECONNECT, &(my_bool){1});mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4") 並在連接前調用。SET NAMES,除非你確定不使用 mysql_real_escape_string 且不開啟自動重連。utf8mb4 而非 utf8,以完整支持 Emoji 及補充字符平面。