C++ Mysql插入中文出错报错,插入中文不显示,插入中文乱码问题

本文测试环境 win10+5.7mysql+vs2017

vs2017工程为多字节字符集,文件编码格式为GB2123,数据库字符集为UTF8

1、插入中文报错

[client]
port=3306
default-character-set=utf8
[mysqld]
# 设置为自己MYSQL的安装目录
basedir=E:\UIClientTool\mysql-5.7.26\bin

# 设置为MYSQL的数据目录
datadir=E:\UIClientTool\mysql-5.7.26\data

port=3306
character_set_server=utf8
sql_mode=NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER

#开启查询缓存
explicit_defaults_for_timestamp=true
#底下代码开启,是数据库每次重启之后不要密码就可以连接数据库,适用于管理员忘记密码时的操作

#skip-grant-tables

default-character-set=utf8

character_set_server=utf8

百度有很多教程,修改配置my.ini文件中上述2个字段重启mysql服务

2、插入中文不显示

当前文件编码格式,GB2312写入到UTF8字符集,存在中文写入为空的情况(图1)

 解决方法:多字节->UNICODE->UTF8写入(ConsoleToUtf8)。转化之后,GB2312 C++可以查看正确中文,写入UTF8也可以查看正常中文。当前取出数据后,要再反转一次,UTF8->GB2312,这样C++才能正常显示中文。(图2)

注:当前cpp文件编码格式为GB2312

3、插入中文乱码

把cpp文件编码格式改为UTF8编码,那么不需要转换,直接存取,那么C++文件和Mysql都将显示乱码,无法查看正常的中文。(图3)

4、示例

1)C++编码格式GB2312:

(1)服务器GB2312中文数据直接保存,则数据库表中文不显示(图1 id:9)。

(2)服务器转换中文为UTF8编码,则数据库显示中文正常(图2 id:10)。

(3)服务器读取UTF8编码格式,传回给客户端,直接传回。如果想要本地C++文件显示,则需要转化为GB2312。

2)C++编码格式UTF8:客户端手机一般为linux utf8编码,传送数据到C++服务器。

(1)服务器直接保存中文数据,则数据库表中文显示乱码(图3 id:13)。

(2)服务器转换中文为GB2312编码,本地C++文件显示正常,存入数据库不显示中文。

(3)服务器读取UTF8编码格式,传回给客户端,直接传回。如果想要本地C++文件显示,则需要转化为GB2312。

结论:

1、Linux服务器:直接UTF8编码格式,本地文件和mysql字符集一样,不需要转换编码,直接存取。显示正常。

2、第一,不能插入数据,一般是配置问题。第二,能插入数据,但不显示,编码问题。第三,能插入数据,乱码,编码问题。

3、Unicode编码直接写入UTF8字符集数据库,尚未测试,结果待定。如果出现问题,参考第三条结论。

4、下面提供转换函数参考:依赖库utf8cpp

ConsoleToUtf8(多字节->Unicode->UTF8) UTF8ToConsole(UTF8->Unicode->多字节) 

bool StringUtility::Utf8toWStr(const std::string & utf8str, std::wstring & wstr)
{
	wstr.clear();
	try
	{
		utf8::utf8to16(utf8str.c_str(), utf8str.c_str() + utf8str.size(), std::back_inserter(wstr));
	}
	catch (std::exception const&)
	{
		wstr.clear();
		return false;
	}

	return true;
}

bool StringUtility::IsBasicLatinCharacter(wchar_t wchar)
{
	if (wchar >= L'a' && wchar <= L'z')                      // LATIN SMALL LETTER A - LATIN SMALL LETTER Z
		return true;
	if (wchar >= L'A' && wchar <= L'Z')                      // LATIN CAPITAL LETTER A - LATIN CAPITAL LETTER Z
		return true;
	return false;
}

wchar_t StringUtility::wcharToUpper(wchar_t wchar)
{
	if (wchar >= L'a' && wchar <= L'z')                      // LATIN SMALL LETTER A - LATIN SMALL LETTER Z
		return wchar_t(uint16(wchar) - 0x0020);
	if (wchar == 0x00DF)                                     // LATIN SMALL LETTER SHARP S
		return wchar_t(0x1E9E);
	if (wchar >= 0x00E0 && wchar <= 0x00F6)                  // LATIN SMALL LETTER A WITH GRAVE - LATIN SMALL LETTER O WITH DIAERESIS
		return wchar_t(uint16(wchar) - 0x0020);
	if (wchar >= 0x00F8 && wchar <= 0x00FE)                  // LATIN SMALL LETTER O WITH STROKE - LATIN SMALL LETTER THORN
		return wchar_t(uint16(wchar) - 0x0020);
	if (wchar >= 0x0101 && wchar <= 0x012F)                  // LATIN SMALL LETTER A WITH MACRON - LATIN SMALL LETTER I WITH OGONEK (only %2=1)
	{
		if (wchar % 2 == 1)
			return wchar_t(uint16(wchar) - 0x0001);
	}
	if (wchar >= 0x0430 && wchar <= 0x044F)                  // CYRILLIC SMALL LETTER A - CYRILLIC SMALL LETTER YA
		return wchar_t(uint16(wchar) - 0x0020);
	if (wchar == 0x0451)                                     // CYRILLIC SMALL LETTER IO
		return wchar_t(0x0401);

	return wchar;
}

wchar_t StringUtility::wcharToUpperOnlyLatin(wchar_t wchar)
{
	return IsBasicLatinCharacter(wchar) ? wcharToUpper(wchar) : wchar;
}

bool StringUtility::WStrToUtf8(std::wstring const & wstr, std::string & utf8str)
{
	try
	{
		std::string utf8str2;
		utf8str2.resize(wstr.size() * 4);                     // allocate for most long case

		if (wstr.size())
		{
			char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str() + wstr.size(), &utf8str2[0]);
			utf8str2.resize(oend - (&utf8str2[0]));                // remove unused tail
		}
		utf8str = utf8str2;
	}
	catch (std::exception const&)
	{
		utf8str.clear();
		return false;
	}

	return true;
}

bool StringUtility::Utf8ToUpperOnlyLatin(std::string & utf8String)
{
	std::wstring wstr;
	if (!Utf8toWStr(utf8String, wstr))
		return false;

	std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin);

	return WStrToUtf8(wstr, utf8String);
}

bool StringUtility::ConsoleToUtf8(const std::string & conStr, std::string & utf8str)
{
	std::wstring wstr;
	wstr.resize(conStr.size());
	OemToCharBuffW(&conStr[0], &wstr[0], uint32(conStr.size()));

	return WStrToUtf8(wstr, utf8str);
}

bool StringUtility::Utf8ToConsole(const std::string& utf8str, std::string& conStr)
{
#if LENDY_PLATFORM == LENDY_PLATFORM_WINDOWS 
	std::wstring wstr;
	if (!Utf8toWStr(utf8str, wstr))
		return false;

	conStr.resize(wstr.size());
	CharToOemBuffW(&wstr[0], &conStr[0], uint32(wstr.size()));
#else
	// not implemented yet
	conStr = utf8str;
#endif
	return true;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL中文数字同时出现导致乱码问题一般是由于字符集设置不正确所导致的。在编写MySQL查询时,我们需要确保数据库连接使用的是正确的字符集。 首先,我们需要确认MySQL数据库的字符集设置。可以通过执行以下查询语句来查看数据库当前的字符集设置: ```sql SHOW VARIABLES LIKE 'character_set%'; ``` 确保以下两个参数的值是utf8utf8mb4: - character_set_client - character_set_connection 如果字符集设置不正确,我们可以通过以下方式来修复这个问题。 1. 修改MySQL配置文件:可以编辑MySQL配置文件my.cnf或my.ini,并在[mysqld]部分添加以下两行配置: ```bash [mysqld] character_set_server = utf8mb4 collation_server = utf8mb4_unicode_ci ``` 2. 修改数据库的默认字符集:可以通过执行以下命令来修改数据库的默认字符集: ```sql ALTER DATABASE database_name DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` 需要将database_name替换为实际的数据库名。 3. 修改表的字符集:可以通过执行以下命令来修改表的字符集: ```sql ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` 需要将table_name替换为实际的表名。 4. 修改连接时的字符集:可以在连接MySQL数据库时指定字符集,例如在连接Java应用程序时可以使用以下代码: ```java String url = "jdbc:mysql://localhost:3306/database_name?useUnicode=true&characterEncoding=utf8mb4"; Connection conn = DriverManager.getConnection(url, username, password); ``` 需要将database_name替换为实际的数据库名。 通过以上步骤,我们可以解决MySQL中文数字同时出现导致的乱码问题。确保数据库连接使用的字符集与文本数据的字符集一致,即可正确显示中文数字。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值