1. 程式人生 > >解決C++連線MySQL資料庫插入和獲取記錄中文字元亂碼問題

解決C++連線MySQL資料庫插入和獲取記錄中文字元亂碼問題

字元編碼真是個頭痛的問題,以前一直不放在心上,現在用到了才發現真的麻煩。

花了將近一天的時間終於達到目的。

測試環境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;
}