C++ 如何在默认c++;项目或使用mysql connector for c++;在visual studio 2019中(拉丁文7\u general\u ci到UTF-8)?

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 #

看起来Latin1ISO-8859-1甚至不能保存特殊字符,所以数据库的格式必须是Latin7ISO-8859-7。真的找不到简单的函数来做这个,我真的要自己写一个吗

更新,更新---我取得了这篇问题文章中描述的小进步-

但是问题似乎出现在没有任何mysql库或任何东西的默认项目设置上,出现在所有正确的编码文件中。(UTF8)即使添加了编译标志,即使安装了“修复文件编码”。

#包括
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),因此来自不同国家的开发人员可以毫无问题地编写代码
      • /execution charset:utf-8
        -表示存储在exactable中的字符串文本应编码为
        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打印分隔符()
      {
      
      标准::cout
      C4 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