C++ 如何在默认c++;项目或使用mysql connector for c++;在visual studio 2019中(拉丁文7\u general\u ci到UTF-8)?
看起来Latin1ISO-8859-1甚至不能保存特殊字符,所以数据库的格式必须是Latin7ISO-8859-7。真的找不到简单的函数来做这个,我真的要自己写一个吗 更新,更新---我取得了这篇问题文章中描述的小进步- 但是问题似乎出现在没有任何mysql库或任何东西的默认项目设置上,出现在所有正确的编码文件中。(UTF8)即使添加了编译标志,即使安装了“修复文件编码”。C++ 如何在默认c++;项目或使用mysql connector for c++;在visual studio 2019中(拉丁文7\u general\u ci到UTF-8)?,c++,mysql,visual-studio,connector,C++,Mysql,Visual Studio,Connector,看起来Latin1ISO-8859-1甚至不能保存特殊字符,所以数据库的格式必须是Latin7ISO-8859-7。真的找不到简单的函数来做这个,我真的要自己写一个吗 更新,更新---我取得了这篇问题文章中描述的小进步- 但是问题似乎出现在没有任何mysql库或任何东西的默认项目设置上,出现在所有正确的编码文件中。(UTF8)即使添加了编译标志,即使安装了“修复文件编码”。 #包括 int main(){ 字符串输出=“āāčēēēē”; 为此,您需要将字符串转换为std::wstring #
#包括
int main(){
字符串输出=“āāčēēēē”;
为此,您需要将字符串转换为std::wstring
#包括
string FirstName=res->getString(“FirstName”);
std::wstring firstNameWstring=std::wstring_convert()。从_字节(FirstName);
我认为您案例中的问题与std::wstring
无关:8位std::string
应该足以支持UTF-8(使用特殊字符创建一个简单的std::string
。
),而取决于操作系统std::wstring
是2字节(Windows)还是4字节(Linux)(更多信息和)。毕竟,如果您查看一下getString
函数,您将看到它接受并返回一个sql::SQLString
。sql::SQLString
类只是一个std::string
的简单包装器
我认为您必须指定utf-8
作为MySql的默认字符集:为此,您必须在连接到数据库时指定:
std::unique_ptr<sql::Connection> connection {nullptr};
try {
sql::Driver* driver = ::get_driver_instance();
sql::ConnectOptionsMap connection_options {};
connection_options["hostName"] = url; // Replace with your log-in
connection_options["userName"] = username; // ...
connection_options["password"] = password; // ...
connection_options["schema"] = schema; // ...
connection_options["characterSetResults"] = "utf8";
connection_options["OPT_CHARSET_NAME"] = "utf8";
connection_options["OPT_SET_CHARSET_NAME"] = "utf8";
connection.reset(driver->connect(connection_options));
} catch (sql::SQLException& ex) {
std::cerr << "Error occured when connecting to SQL data base: " << ex.what() << "(" << ex.getErrorCode() << ").";
}
它将输出C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1
,然后将其插回一个字节到utf8的转换器中,这实际上会给您āīīēļš
。因此字符串读取正确,但Windows无法正确显示它。以下内容与上一节结合使用(在MySql中将utf-8
指定为默认字符集)应该可以解决所有问题:
- 在程序开始时,从
调用windows.h
将修复控制台输出:设置控制台输出CP(CP_UTF8);
#include <cstdlib> #include <iostream> #include <string> #include <windows.h> int main() { // Forces console output to UTF8 SetConsoleOutputCP(CP_UTF8); std::string const name = u8"āàčīēļš"; std::cout << name << std::endl; // Actually outputs āàčīēļš return EXIT_SUCCESS; }
- 问题在于代码的不同部分使用不同的文本数据编码
由于MySql使用的是
utf-8
,您只需将程序更改为在任何地方都使用utf-8
。
这可以通过生成标志来实现:
cl/源字符集:utf-8/执行字符集:utf-8/EHsc YourSources.cpp
-表示您的源文件使用的是/source charset:utf-8
编码-因为您的源代码可以使用不同的编码,所以请确保您使用的参数正确,但强烈建议源代码采用通用的标准编码(因此utf-8),因此来自不同国家的开发人员可以毫无问题地编写代码utf-8
-表示存储在exactable中的字符串文本应编码为/execution charset:utf-8
utf-8
cmd
)。默认情况下,Windows控制台使用特定于系统上语言设置的编码(继承与旧DOS应用程序的兼容性)。因此,当您强制可执行文件使用utf-8
时,默认情况下控制台将错误地打印这些代码
更改控制台的代码页,使其使用utf-8
将解决此问题
下面是我编写的一个测试程序,演示如何在C++中处理编码:
#包括
#包括
#包括
#包括
void setupLocale(int argc,const char*argv[])
{
std::locale def{“};
std::locale::global(argc>1?std::locale{argv[1]}:def);
autostreamlocale=argc>2?std::locale{argv[2]}:def;
标准::cout.imbue(streamLocale);
标准::cin.imbue(streamLocale);
}
void打印分隔符()
{
标准::coutC4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1
,当解释为各种编码时:
utf8: āàčīēļš
latin1: Äà Äīēļš
latin7: ÄĆÄ Ä Ä«ÄļŔ
euckr 훮횪훾카휆캬큄
大概您想要utf8(或utf8mb4)
连接参数指定客户端的编码。如果该十六进制字符串来自客户端,则指定utf8(或utf8mb4)
数据库表中的编码可以相同,也可以不同。这在架构中指定;例如:
CREATE TABLE ...
stuff VARCHAR(99) CHARACTER SET utf8
...
当插入
和选择
时,MySQL将在客户端编码和列编码之间进行转换(如果需要)
发现:
要查看客户端设置,请执行以下操作:
SHOW VARIABLES LIKE 'char%';
:--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin7 | <--
| character_set_connection | latin7 | <--
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | latin7 | <--
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
几乎所有其他技术都容易出错
请注意,您提到的重音字符都具有UTF-8十六进制字符
C3 xx
C4 xx
C5 xx
术语:
然后“字符集”被编码。例如:拉丁1,拉丁7,utf8,utf8mb4
“排序规则”指的是如何对值进行排序和比较。例如:latin7_general_ci(“ci”是“不区分大小写,不区分重音”的缩写)
(您的连接参数混淆了字符集和排序规则。)
“utf8”或“utf8mb3”是MySQL的3字节编码。虽然已经消失了,但对所有欧洲语言以及世界其他大部分语言仍然非常有效
“utf8mb4”是MySQL的4字节编码,相当于UTF-8
“UTF-8”是世界其他地方对它的称呼
常见错误:
- 未能声明客户端的编码
- 尝试在客户端中转换编码
Visual studio允许您更改文件编码。
因此,如果要在变量上键入字符,则应使用该编码
在Visual Studio中或以编程方式设置该选项
打开“项目属性页”对话框。。。
选择配置属性
std::string const some_query = "SELECT * FROM some_table_name;";
std::unique_ptr<sql::Statement> statement {connection->createStatement()};
std::unique_ptr<sql::ResultSet> result {statement->executeQuery(some_query)};
while (result->next()) {
std::string const some_field = result->getString("some_field_name");
// Process: e.g. display with std::cout << some_field << std::endl;
}
void dump_bytes(std::string const& str) {
std::cout << std::hex << std::uppercase << std::setfill('0');
for (unsigned char c : str) {
std::cout << std::setw(2) << static_cast<int>(c) << ' ';
}
std::cout << std::dec << std::endl;
return;
}
#include <cstdlib>
#include <iostream>
#include <string>
#include <windows.h>
int main() {
// Forces console output to UTF8
SetConsoleOutputCP(CP_UTF8);
std::string const name = u8"āàčīēļš";
std::cout << name << std::endl; // Actually outputs āàčīēļš
return EXIT_SUCCESS;
}
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <string>
int main() {
std::string const name = u8"āàčīēļš";
std::ofstream f(std::filesystem::u8path(name + ".txt")); // Creates a file āàčīēļš.txt
f << name << std::endl; // Writes āàčīēļš to it
return EXIT_SUCCESS;
}
utf8: āàčīēļš
latin1: Äà Äīēļš
latin7: ÄĆÄ Ä Ä«ÄļŔ
euckr 훮횪훾카휆캬큄
CREATE TABLE ...
stuff VARCHAR(99) CHARACTER SET utf8
...
SHOW VARIABLES LIKE 'char%';
:--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin7 | <--
| character_set_connection | latin7 | <--
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | latin7 | <--
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
SELECT col, HEX(col) ...
C3 xx
C4 xx
C5 xx