sql >> Databasteknik >  >> RDS >> Mysql

Hur använder man UTF8-tecken i DEFAULT c++-projekt ELLER när man använder mysql-kontakt för c++ i Visual Studio 2019 (Latin7_general_ci till UTF-8)?

Jag tror att problemet i ditt fall inte är relaterat till std::wstring :8-bitars std::string bör vara tillräckligt för UTF-8 (att skapa en enkel std::string med specialtecknen "āàčīēļš" fungerar bara bra), medan det beror på operativsystemet std::wstring är 2 byte (Windows) eller 4 byte (Linux) (mer information här och här ). När allt kommer omkring om du tittar på getString funktion kommer du att se att den tar och returnerar en sql::SQLString . sql::SQLString klass är bara ett enkelt omslag för en std::string .

Jag tror att du måste specificera utf-8 som standardteckenuppsättning för MySql :För detta måste du ange följande anslutningsalternativ när du ansluter till databasen:

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

Då bör du kunna fortsätta att fråga din databas enligt följande

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

Problemet som nu uppstår när du vill skapa filnamn med den eller mata ut den till konsolen är Windows själv (jag hade testat koden tidigare med endast Linux och stötte därför inte på det här problemet tidigare!):Som standard använder den ANSI och inte UTF-8. Även om du matar ut något som āàčīēļš det kommer inte att mata ut det korrekt oavsett om du använder en std::cout eller std::wcout i kombination med std::wstring . Istället kommer den att mata ut ─ü├á─ì─½─ô─╝┼í .

Om du extraherar byte

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

den kommer att mata ut C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1 som kopplar tillbaka den till en byte-till-utf8-omvandlare som denna ger dig faktiskt āàčīēļš . Så strängen lästes korrekt men Windows visar den inte korrekt. Följande i kombination med det sista avsnittet (specificerar utf-8 som standardteckenuppsättning i MySql) bör lösa alla dina problem:

  • Ett anrop till SetConsoleOutputCP(CP_UTF8); från windows.h i början av programmet fixar konsolutgången :

     #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;
     }
    
  • På samma sätt måste du anpassa din rutin som skapar filerna som standard kommer det inte att vara UTF8 också (innehållet i filerna kommer inte att vara ett problem men själva filnamnet kommer att vara det!). Använd std::ofstream från fstream i kombination med std::filesystem::u8path från C++17-biblioteket filesystem för att lösa detta:

     #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. kan inte lägga till mysql db-tabell i vb-datakällan

  2. Hur man listar tabeller i MySQL och MariaDB

  3. Inbäddad Postgres för Spring Boot Tests

  4. Postgres-funktion för att validera e-postadress