Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да използвам UTF8 знаци в проекта DEFAULT c++ ИЛИ, когато използвам mysql конектор за c++ във Visual Studio 2019 (Latin7_general_ci към UTF-8)?

Мисля, че проблемът във вашия случай не е свързан с 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() << ").";
}

След това трябва да можете да продължите да правите запитвания към вашата база данни, както следва

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

Проблемът, който сега възниква, когато искате да създадете имена на файлове с него или да го изведете в конзолата, е Windows себе си (бях тествал кода преди само с Linux и следователно не се сблъсках с този проблем преди!):По подразбиране той използва ANSI, а не UTF-8. Дори ако изведете нещо като āàčīēļš няма да го изведе правилно, независимо дали използвате std::cout или std::wcout в комбинация с std::wstring . Вместо това ще изведе ─ü├á─ì─½─ô─╝┼í .

Ако извлечете байтовете

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

ще изведе C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1 което го включва обратно в байт-към-utf8-конвертор като този всъщност ще ви даде āàčīēļš . Така че низът е прочетен правилно, но Windows просто не го показва правилно. Следното в комбинация с последния раздел (посочващ utf-8 като набор от символи по подразбиране в MySql) трябва да коригира всичките ви проблеми:

  • Извикване на SetConsoleOutputCP(CP_UTF8); от windows.h в началото на програмата ще коригира конзолния изход :

     #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;
     }
    
  • По същия начин ще трябва да адаптирате вашата рутина, която създава файловете тъй като по подразбиране също няма да бъде UTF8 (съдържанието на файловете няма да е проблем, но самото име на файла ще бъде!). Използвайте std::ofstream от fstream в комбинация с std::filesystem::u8path от filesystem на библиотеката C++17 за да разрешите това:

     #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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Променете динамично името на колоната в PDO израза

  2. SQL LEFT-JOIN на 2 полета за MySQL

  3. Установете обединена връзка с MySQL в android

  4. Mysql - повторно използване на изчислени стойности

  5. Rails 4 Проверка на уникалността на имейла без чувствителен на регистър