sql >> Database >  >> RDS >> Mysql

Hoe UTF8-tekens te gebruiken in het DEFAULT c++-project OF bij gebruik van mysql-connector voor c++ in visual studio 2019 (Latin7_general_ci tot UTF-8)?

Ik denk dat het probleem in jouw geval niet te maken heeft met std::wstring :de 8-bits std::string zou voldoende moeten zijn voor UTF-8 (maak een eenvoudige std::string met de speciale tekens "āàčīēļš" werkt gewoon prima), terwijl afhankelijk van het besturingssysteem std::wstring is 2 Byte (Windows) of 4 Byte (Linux) (meer informatie hier en hier ). Immers, als je de getString . bekijkt functie zul je zien dat het een sql::SQLString . vereist en retourneert . De sql::SQLString class is slechts een eenvoudige wrapper voor een std::string .

Ik denk dat je opgeeft utf-8 als standaard tekenset voor MySql :Hiervoor moet u de volgende verbindingsopties bij verbinding met de database:

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

Dan zou u als volgt door moeten kunnen gaan met het doorzoeken van uw database

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

Het probleem dat zich nu voordoet wanneer u er bestandsnamen mee wilt maken of naar de console wilt uitvoeren, is Windows zelf (ik had de code eerder alleen met Linux getest en ben daarom dit probleem niet eerder tegengekomen!):Standaard gebruikt het ANSI en niet UTF-8. Zelfs als je iets als āàčīēļš . uitvoert het zal het niet correct uitvoeren, ongeacht of je een std::cout . gebruikt of std::wcout in combinatie met std::wstring . In plaats daarvan zal het ─ü├á─ì─½─ô─╝┼í . uitvoeren .

Als u de bytes extraheert

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

het zal C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1 uitvoeren die het weer aansluit op een byte-naar-utf8-converter zoals deze zal je in feite āàčīēļš . geven . Dus de string is correct gelezen, maar Windows geeft deze gewoon niet correct weer. Het volgende in combinatie met de laatste sectie (met vermelding van utf-8 als standaard tekenset in MySql) zou al je problemen moeten oplossen:

  • Een aanroep naar SetConsoleOutputCP(CP_UTF8); van windows.h aan het begin van het programma herstelt de console-uitvoer :

     #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;
     }
    
  • Evenzo zult u uw routine moeten aanpassen die de bestanden . aanmaakt omdat het standaard ook geen UTF8 is (de inhoud van de bestanden zal geen probleem zijn, maar de bestandsnaam zelf wel!). Gebruik std::ofstream van fstream in combinatie met std::filesystem::u8path uit de C++17-bibliotheek filesystem om dit op te lossen:

     #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. datetime naar totalminute in sql

  2. PHP - MySQL - Rij verwijderen

  3. Matrix voor door SQL Server ondersteunde versies

  4. Beste structuur voor een relationele database met artikelen en tags