Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Cách sử dụng các ký tự UTF8 trong dự án DEFAULT c ++ HOẶC khi sử dụng trình kết nối mysql cho c ++ trong visual studio 2019 (Latin7_general_ci thành UTF-8)?

Tôi nghĩ rằng vấn đề trong trường hợp của bạn không liên quan đến std::wstring :std::string 8 bit phải đủ cho UTF-8 (tạo một std::string đơn giản với các ký tự đặc biệt "āàčīēļš" chỉ hoạt động tốt), trong khi tùy thuộc vào hệ điều hành std::wstring là 2 Byte (Windows) hoặc 4 Byte (Linux) (thêm thông tin tại đây tại đây ). Sau tất cả, nếu bạn đã xem getString bạn sẽ thấy rằng nó nhận và trả về một sql::SQLString . sql::SQLString lớp chỉ là một trình bao bọc đơn giản cho một std::string .

Tôi nghĩ bạn phải chỉ định utf-8 làm ký tự mặc định được đặt cho MySql :Đối với điều này, bạn sẽ phải chỉ định các tùy chọn kết nối sau khi kết nối với cơ sở dữ liệu:

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

Sau đó, bạn sẽ có thể tiếp tục truy vấn cơ sở dữ liệu của mình như sau

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

Sự cố bây giờ xuất hiện khi bạn muốn tạo tên tệp với nó hoặc xuất nó ra bảng điều khiển là Windows (Tôi đã thử nghiệm mã trước đây chỉ với Linux và do đó không gặp phải vấn đề này trước đây!):Theo mặc định, nó sử dụng ANSI chứ không phải UTF-8. Ngay cả khi bạn xuất một cái gì đó như āàčīēļš nó sẽ không xuất ra chính xác cho dù bạn đang sử dụng std::cout hoặc std::wcout kết hợp với std::wstring . Thay vào đó, nó sẽ xuất ra ─ü├á─ì─½─ô─╝┼í .

Nếu bạn trích xuất các 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;
}

nó sẽ xuất ra C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1 cắm lại nó vào bộ chuyển đổi byte-to-utf8, chẳng hạn như cái này thực tế sẽ cung cấp cho bạn āàčīēļš . Vì vậy, chuỗi đã được đọc chính xác nhưng Windows không hiển thị chính xác. Phần sau kết hợp với phần cuối cùng (chỉ định utf-8 làm ký tự mặc định được đặt trong MySql) sẽ khắc phục tất cả các vấn đề của bạn:

  • Lệnh gọi đến SetConsoleOutputCP(CP_UTF8); từ windows.h khi bắt đầu chương trình sẽ sửa đầu ra bảng điều khiển :

     #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;
     }
    
  • Tương tự, bạn sẽ phải điều chỉnh quy trình tạo tệp theo mặc định, nó cũng sẽ không phải là UTF8 (Nội dung của các tệp sẽ không phải là vấn đề nhưng chính tên tệp sẽ có!). Sử dụng std::ofstream từ fstream kết hợp với std::filesystem::u8path từ thư viện C ++ 17 filesystem để giải quyết vấn đề này:

     #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. đúng cú pháp để sử dụng gần '?'

  2. thay đổi công cụ mặc định mysql thành innodb

  3. Lấy dữ liệu từ mysql và hiển thị dưới dạng bảng văn bản ascii trong trình duyệt

  4. Có chế độ SQL nào cho MySQL cho phép WHERE x =NULL (nghĩa là WHERE x LÀ NULL) không?

  5. Không thể kết nối với máy chủ MySQL trên MySQLCC ERROR 1043 Bad Handshake