解決C++連線MySQL資料庫插入和獲取記錄中文字元亂碼問題
阿新 • • 發佈:2019-01-02
字元編碼真是個頭痛的問題,以前一直不放在心上,現在用到了才發現真的麻煩。
花了將近一天的時間終於達到目的。
測試環境VS2015+MYSQL5.5,各種編碼的具體說明就不講了,自行百度。
1、讀取資料亂碼問題:
vs專案下,預設編碼Unicode,但我的資料庫預設utf8,所以讀取資料的時候中文亂碼。
百度了一下,發現只要將utf8字元轉成unicode字元即可,轉換函式如下:
wchar_t* Utf8_2_Unicode(char* row_i) { int len = MultiByteToWideChar(CP_UTF8, 0, row_i, strlen(row_i), NULL, 0); wchar_t *wszStr = new wchar_t[len + 1]; MultiByteToWideChar(CP_UTF8, 0, row_i, strlen(row_i), wszStr, len); wszStr[len] = '\0'; return wszStr; }
在函式外部定義一個wchar_t*型別變數接收返回值即可正確輸出。
2、寫入資料亂碼
解決了讀取出錯後以為讀取只要反向轉換就行,但是把接收到的utf8字元轉換成unicode後並不能行。
然後在網上各種百度,然後又各種型別轉換編碼轉換人都弄暈了,總是圍繞utf8轉來轉去,沒有一點成效。
最後看了一個帖子,說要以gbk形式寫入,在內心抱著極度懷疑的情況下試了一下,沒想到竟然成功了。
其實這個帖子看了很多遍了,在心裡默默的排除了一萬遍沒想到最後竟然它才是有用的。
方法很簡單,只要在寫入之前設定編碼為gbk即可。
strcpy_s(sql, "set names gbk");
3、完整的測試程式碼
#include "d:/include/mysql.h" #include <iostream> #include <windows.h> #include <tchar.h> using namespace std; #pragma comment(lib, "d:/lib/libmysql.lib") wchar_t* Utf8_2_Unicode(char* row_i) { int len = MultiByteToWideChar(CP_UTF8, 0, row_i, strlen(row_i), NULL, 0); wchar_t *wszStr = new wchar_t[len + 1]; MultiByteToWideChar(CP_UTF8, 0, row_i, strlen(row_i), wszStr, len); wszStr[len] = '\0'; return wszStr; } void showError(const char * error) { cout << error << endl; getchar(); } int main() { MYSQL mysql; MYSQL *connect; //初始化MYSQL connect = mysql_init(&mysql); if (connect == NULL) { showError(mysql_error(connect)); return mysql_errno(connect); } cout << "Init OK" << endl; //連線到MYSQL connect = mysql_real_connect(connect, "localhost", "root", "123456", "mytest", 3306, NULL, 0); if (connect == NULL) { showError(mysql_error(connect)); return mysql_errno(connect); } cout << "Connect OK" << endl; char sql[256] = {0}; //將編碼設定為gbk strcpy_s(sql, "set names gbk"); if (mysql_query(connect, sql)) { showError(mysql_error(connect)); return mysql_errno(connect); } //寫入中文資料 strcpy_s(sql, "INSERT INTO test(m1, m2) VALUES('測試', 'Test')"); if (mysql_query(connect, sql)) { showError(mysql_error(connect)); return mysql_errno(connect); } cout << "Insert success!\n"; //設定編碼格式utf8 strcpy_s(sql, "set names utf8"); int ret = mysql_query(connect, sql); if (ret) { showError(mysql_error(connect)); return mysql_errno(connect); } //讀取中文資料 strcpy_s(sql, "SELECT * FROM test"); ret = mysql_query(connect, sql); if (ret) { showError(mysql_error(connect)); return mysql_errno(connect); } else { //獲取結果集 MYSQL_RES *res = mysql_store_result(connect); if (mysql_num_rows(res) == NULL) { showError(mysql_error(connect)); return mysql_errno(connect); } int nfieldNum = mysql_num_fields(res); MYSQL_ROW row; //取出結果集 while (row = mysql_fetch_row(res)) { wchar_t *m1, *m2; //將字元由utf8專轉為unicode m1 = Utf8_2_Unicode(row[0]); m2 = Utf8_2_Unicode(row[1]); MessageBox(NULL, m1, m2, NULL); } mysql_free_result(res); } mysql_close(connect); getchar(); return 0; }