sql >> Database teknologi >  >> RDS >> Mysql

Hvordan bruger man UTF8-tegn i DEFAULT c++-projekt ELLER når man bruger mysql-stik til c++ i Visual Studio 2019 (Latin7_general_ci til UTF-8)?

Jeg tror, ​​at problemet i dit tilfælde ikke er relateret til std::wstring :8-bit std::string burde være tilstrækkeligt til UTF-8 (opretter en simpel std::string med specialtegnene "āàčīēļš" fungerer bare fint), mens det afhænger af operativsystemet std::wstring er 2 Byte (Windows) eller 4 Byte (Linux) (mere information her og her ). Når alt kommer til alt, hvis du har et kig på getString funktion vil du se, at den tager og returnerer en sql::SQLString . sql::SQLString klasse er blot en simpel indpakning for en std::string .

Jeg tror, ​​du skal specificere utf-8 som standardtegnsæt for MySql :Til dette skal du angive følgende tilslutningsmuligheder ved tilslutning til 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() << ").";
}

Så skulle du kunne fortsætte med at forespørge i din database som følger

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, der nu dukker op, når du vil oprette filnavne med det eller udlæse det til konsollen, er Windows selv (jeg havde kun testet koden før med Linux og stødte derfor ikke på dette problem før!):Som standard bruger den ANSI og ikke UTF-8. Selv hvis du udsender noget som āàčīēļš det vil ikke udlæse det korrekt, uanset om du bruger en std::cout eller std::wcout i kombination med std::wstring . I stedet vil den udsende ─ü├á─ì─½─ô─╝┼í .

Hvis du udpakker bytes

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 udsender C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1 som sætter den tilbage i en byte-til-utf8-konverter, såsom denne vil faktisk give dig āàčīēļš . Så strengen blev læst korrekt, men Windows viser den bare ikke korrekt. Det følgende i kombination med det sidste afsnit (angiver utf-8 som standardtegnsæt i MySql) skulle løse alle dine problemer:

  • Et kald til SetConsoleOutputCP(CP_UTF8); fra windows.h i starten af ​​programmet vil rette konsoloutputtet :

     #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å samme måde bliver du nødt til at tilpasse din rutine, der opretter filerne da det som standard ikke også vil være UTF8 (indholdet af filerne vil ikke være et problem, men selve filnavnet vil være det!). Brug std::ofstream fra fstream i kombination med std::filesystem::u8path fra C++17-biblioteket filesystem for at løse dette:

     #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. group_concat ydeevneproblem i MySQL

  2. Kan ikke importere MySQLdb-modul i Python

  3. SQL:Er det muligt at SUMMER() felter af typen INTERVAL?

  4. Hvordan læser man specifik kolonne og celle i mysql i c#?