sql >> Databáze >  >> RDS >> Mysql

Jak používat znaky UTF8 v projektu DEFAULT c++ NEBO při použití konektoru mysql pro c++ ve Visual Studio 2019 (Latin7_general_ci až UTF-8)?

Myslím, že problém ve vašem případě nesouvisí s std::wstring :8bitový std::string by mělo být dostatečné pro UTF-8 (vytvoření jednoduchého std::string se speciálními znaky "āàčīēļš" funguje dobře), zatímco v závislosti na operačním systému std::wstring je 2 bajty (Windows) nebo 4 bajty (Linux) (více informací zde a zde ). Koneckonců, když se podíváte na getString funkce, uvidíte, že bere a vrací sql::SQLString . sql::SQLString class je jen jednoduchý obal pro std::string .

Myslím, že musíte zadat utf-8 jako výchozí znakovou sadu pro MySql :K tomu budete muset zadat následující možnosti připojení při připojení k databázi:

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() << ").";
}

Poté byste měli být schopni pokračovat v dotazování vaší databáze následovně

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;
}

Problém, který se nyní objeví, když s ním chcete vytvořit názvy souborů nebo jej odeslat do konzoly, je Windows sám (kód jsem předtím testoval pouze s Linuxem, a proto jsem se s tímto problémem dříve nesetkal!):Ve výchozím nastavení používá ANSI a ne UTF-8. I když vypíšete něco jako āàčīēļš nebude to vypisovat správně bez ohledu na to, zda používáte std::cout nebo std::wcout v kombinaci s std::wstring . Místo toho vypíše ─ü├á─ì─½─ô─╝┼í .

Pokud extrahujete bajty

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;
}

bude na výstupu C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1 který jej zapojí zpět do převodníku byte-to-utf8, jako je tento ve skutečnosti vám poskytne āàčīēļš . Řetězec byl tedy přečten správně, ale systém Windows jej nezobrazuje správně. Následující v kombinaci s poslední částí (určující utf-8 jako výchozí znaková sada v MySql) by měl vyřešit všechny vaše problémy:

  • Volání SetConsoleOutputCP(CP_UTF8); z windows.h při startu programu opraví výstup konzole :

     #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;
     }
    
  • Podobně budete muset přizpůsobit svou rutinu, která vytváří soubory jako výchozí nebude také UTF8 (Obsah souborů nebude problém, ale samotný název souboru ano!). Použijte std::ofstream z fstream v kombinaci s std::filesystem::u8path z knihovny C++17 filesystem jak to vyřešit:

     #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;
     }
    


  1. mysql - přesun řádků z jedné tabulky do druhé

  2. Použití Pythonu a MySQL v procesu ETL:SQLAlchemy

  3. Problémy s TransactionScope a Oracle

  4. MySQL Error 1 (HY000) Problém s vytvářením souboru Errcode 2