[英]How to use UTF8 characters in DEFAULT c++ project OR when using mysql connector for c++ in visual studio 2019 (Latin7_general_ci to UTF-8)?
SEEMS LIKE Latin1 ISO-8859-1 甚至不能保存特殊字符,所以数据库的格式必须是 Latin7 ISO-8859-7。 真的找不到容易的 function 来做到这一点,我真的必须自己写一个吗?
更新,更新 --- 我取得了小进展,如本文所述 - Visual Studio 2019 C++ 项目中的特殊字符并使用它们执行 CMD 命令
但问题似乎出现在默认项目设置上,没有任何 mysql 库或任何东西,在所有正确编码的文件中。 (UTF8) 即使添加了编译标志,即使安装了“修复文件编码”。
#include <iostream>
int main() {
string output = "āāāčččēēēē";
cout << output << endl;
}
Intro rant* - This is 3rd post about MySql Connector, because I just could not find basic information about MySql Connector in Google at all ( MySQL and MariaDB library's in C++ using cmake, mingw ), first there was no explanation that GCC will not be able to compile it for Windows systems, then I had no luck finding how to use datetime and int objects in the output from database, until I posted issue here ( How to return time, date data fields in c++ mysql oracle vs17? ).
我现在的问题是从数据库返回的字符串有特殊字符 - āàčīēļš 等。 列:test2col 排序:Latin7_general_ci
所以这里是可能有效的代码,但不是由于表格或错误,任何专业知识都可能有所帮助:
#include <iostream>
#include <string>
#include <string_view>
std::string_view itou[256] {
{"\x00",1} , {"\x01",1} , {"\x02",1} , {"\x03",1} ,
{"\x04",1} , {"\x05",1} , {"\x06",1} , {"\x07",1} ,
{"\x08",1} , {"\x09",1} , {"\x0a",1} , {"\x0b",1} ,
{"\x0c",1} , {"\x0d",1} , {"\x0e",1} , {"\x0f",1} ,
{"\x10",1} , {"\x11",1} , {"\x12",1} , {"\x13",1} ,
{"\x14",1} , {"\x15",1} , {"\x16",1} , {"\x17",1} ,
{"\x18",1} , {"\x19",1} , {"\x1a",1} , {"\x1b",1} ,
{"\x1c",1} , {"\x1d",1} , {"\x1e",1} , {"\x1f",1} ,
{"\x20",1} , {"\x21",1} , {"\x22",1} , {"\x23",1} ,
{"\x24",1} , {"\x25",1} , {"\x26",1} , {"\x27",1} ,
{"\x28",1} , {"\x29",1} , {"\x2a",1} , {"\x2b",1} ,
{"\x2c",1} , {"\x2d",1} , {"\x2e",1} , {"\x2f",1} ,
{"\x30",1} , {"\x31",1} , {"\x32",1} , {"\x33",1} ,
{"\x34",1} , {"\x35",1} , {"\x36",1} , {"\x37",1} ,
{"\x38",1} , {"\x39",1} , {"\x3a",1} , {"\x3b",1} ,
{"\x3c",1} , {"\x3d",1} , {"\x3e",1} , {"\x3f",1} ,
{"\x40",1} , {"\x41",1} , {"\x42",1} , {"\x43",1} ,
{"\x44",1} , {"\x45",1} , {"\x46",1} , {"\x47",1} ,
{"\x48",1} , {"\x49",1} , {"\x4a",1} , {"\x4b",1} ,
{"\x4c",1} , {"\x4d",1} , {"\x4e",1} , {"\x4f",1} ,
{"\x50",1} , {"\x51",1} , {"\x52",1} , {"\x53",1} ,
{"\x54",1} , {"\x55",1} , {"\x56",1} , {"\x57",1} ,
{"\x58",1} , {"\x59",1} , {"\x5a",1} , {"\x5b",1} ,
{"\x5c",1} , {"\x5d",1} , {"\x5e",1} , {"\x5f",1} ,
{"\x60",1} , {"\x61",1} , {"\x62",1} , {"\x63",1} ,
{"\x64",1} , {"\x65",1} , {"\x66",1} , {"\x67",1} ,
{"\x68",1} , {"\x69",1} , {"\x6a",1} , {"\x6b",1} ,
{"\x6c",1} , {"\x6d",1} , {"\x6e",1} , {"\x6f",1} ,
{"\x70",1} , {"\x71",1} , {"\x72",1} , {"\x73",1} ,
{"\x74",1} , {"\x75",1} , {"\x76",1} , {"\x77",1} ,
{"\x78",1} , {"\x79",1} , {"\x7a",1} , {"\x7b",1} ,
{"\x7c",1} , {"\x7d",1} , {"\x7e",1} , {"\x7f",1} ,
{"\xc2""\x80",2} , {"\xc2""\x81",2} , {"\xc2""\x82",2} , {"\xc2""\x83",2} ,
{"\xc2""\x84",2} , {"\xc2""\x85",2} , {"\xc2""\x86",2} , {"\xc2""\x87",2} ,
{"\xc2""\x88",2} , {"\xc2""\x89",2} , {"\xc2""\x8a",2} , {"\xc2""\x8b",2} ,
{"\xc2""\x8c",2} , {"\xc2""\x8d",2} , {"\xc2""\x8e",2} , {"\xc2""\x8f",2} ,
{"\xc2""\x90",2} , {"\xc2""\x91",2} , {"\xc2""\x92",2} , {"\xc2""\x93",2} ,
{"\xc2""\x94",2} , {"\xc2""\x95",2} , {"\xc2""\x96",2} , {"\xc2""\x97",2} ,
{"\xc2""\x98",2} , {"\xc2""\x99",2} , {"\xc2""\x9a",2} , {"\xc2""\x9b",2} ,
{"\xc2""\x9c",2} , {"\xc2""\x9d",2} , {"\xc2""\x9e",2} , {"\xc2""\x9f",2} ,
{"\xc2""\xa0",2} , {"\xe2""\x80""\x98",3}, {"\xe2""\x80""\x99",3}, {"\xc2""\xa3",2} ,
{"\xe2""\x82""\xac",3}, {"\xe2""\x82""\xaf",3}, {"\xc2""\xa6",2} , {"\xc2""\xa7",2} ,
{"\xc2""\xa8",2} , {"\xc2""\xa9",2} , {"\xcd""\xba",2} , {"\xc2""\xab",2} ,
{"\xc2""\xac",2} , {"\xc2""\xad",2} , {"\x3f",1} , {"\xe2""\x80""\x95",3},
{"\xc2""\xb0",2} , {"\xc2""\xb1",2} , {"\xc2""\xb2",2} , {"\xc2""\xb3",2} ,
{"\xce""\x84",2} , {"\xce""\x85",2} , {"\xce""\x86",2} , {"\xc2""\xb7",2} ,
{"\xce""\x88",2} , {"\xce""\x89",2} , {"\xce""\x8a",2} , {"\xc2""\xbb",2} ,
{"\xce""\x8c",2} , {"\xc2""\xbd",2} , {"\xce""\x8e",2} , {"\xce""\x8f",2} ,
{"\xce""\x90",2} , {"\xce""\x91",2} , {"\xce""\x92",2} , {"\xce""\x93",2} ,
{"\xce""\x94",2} , {"\xce""\x95",2} , {"\xce""\x96",2} , {"\xce""\x97",2} ,
{"\xce""\x98",2} , {"\xce""\x99",2} , {"\xce""\x9a",2} , {"\xce""\x9b",2} ,
{"\xce""\x9c",2} , {"\xce""\x9d",2} , {"\xce""\x9e",2} , {"\xce""\x9f",2} ,
{"\xce""\xa0",2} , {"\xce""\xa1",2} , {"\x3f",1} , {"\xce""\xa3",2} ,
{"\xce""\xa4",2} , {"\xce""\xa5",2} , {"\xce""\xa6",2} , {"\xce""\xa7",2} ,
{"\xce""\xa8",2} , {"\xce""\xa9",2} , {"\xce""\xaa",2} , {"\xce""\xab",2} ,
{"\xce""\xac",2} , {"\xce""\xad",2} , {"\xce""\xae",2} , {"\xce""\xaf",2} ,
{"\xce""\xb0",2} , {"\xce""\xb1",2} , {"\xce""\xb2",2} , {"\xce""\xb3",2} ,
{"\xce""\xb4",2} , {"\xce""\xb5",2} , {"\xce""\xb6",2} , {"\xce""\xb7",2} ,
{"\xce""\xb8",2} , {"\xce""\xb9",2} , {"\xce""\xba",2} , {"\xce""\xbb",2} ,
{"\xce""\xbc",2} , {"\xce""\xbd",2} , {"\xce""\xbe",2} , {"\xce""\xbf",2} ,
{"\xcf""\x80",2} , {"\xcf""\x81",2} , {"\xcf""\x82",2} , {"\xcf""\x83",2} ,
{"\xcf""\x84",2} , {"\xcf""\x85",2} , {"\xcf""\x86",2} , {"\xcf""\x87",2} ,
{"\xcf""\x88",2} , {"\xcf""\x89",2} , {"\xcf""\x8a",2} , {"\xcf""\x8b",2} ,
{"\xcf""\x8c",2} , {"\xcf""\x8d",2} , {"\xcf""\x8e",2} , {"\x3f",1}
};
int main() {
std::string input{"āāāčččēēēē"};
std::string output;
for (auto c : input) {
output.append(itou[static_cast<uint8_t>(c)]);
}
std::cout << output << std::endl;
}
string FirstName = res->getString("test2col");
MySQL 连接器的文档:https://dev.mysql.com/doc/dev/connector-cpp/8.0/
似乎对此没有太多了解,所以感谢您的帮助!
所以这里的代码示例会根据评论中的解决方案变成另一个错误 -
157
#include <iostream>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <string>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <cstring>
#include <filesystem>
#include <codecvt>
#include <cstdint>
#include <locale>
Severity Code Description Project File Line Suppression State Error C4996 'std::wstring_convert<std::codecvt_utf8<wchar_t,1114111,(std::codecvt_mode)0>,wchar_t,std::allocator<wchar_t>,std::allocator<char>>::to_bytes': warning STL4017: std::wbuffer_convert, std::wstring_convert, and the <codecvt> header (containing std::codecvt_mode, std::codecvt_utf8, std::codecvt_utf16, and std::codecvt_utf8_utf16) are deprecated in C++17. (The std::codecvt class template is NOT deprecated.) The C++ Standard doesn't provide equivalent non-deprecated functionality; consider using MultiByteToWideChar() and WideCharToMultiByte() from <Windows.h> instead. You can define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.
```cpp
try
{
std::unique_ptr<sql::Connection> connection{ nullptr };
try {
sql::Driver* driver = ::get_driver_instance();
//sql::Connection* con;
//sql::Statement *stmt;
//sql::ResultSet* res;
//sql::Statement* pstmt;
sql::ConnectOptionsMap connection_options{};
connection_options["hostName"] = "tcp://127.0.0.1:3306"; // Replace with your log-in
connection_options["userName"] = "root"; // ...
connection_options["password"] = "parole123!"; // ...
connection_options["schema"] = "test"; // ...
connection_options["characterSetResults"] = "latin7_general_ci";
connection_options["OPT_CHARSET_NAME"] = "latin7_general_ci";
connection_options["OPT_SET_CHARSET_NAME"] = "latin7_general_ci";
connection.reset(driver->connect(connection_options));
driver = get_driver_instance();
/* Create a connection */
//con = driver->connect("tcp://127.0.0.1:3306", "root", "parole123!");
//con->setClientOption("characterSetResults", "UTF8");
/* Connect to the MySQL test database */
//con->setSchema("test");
//pstmt = con->createStatement();
std::string const some_query = "SELECT * FROM test2";
std::unique_ptr<sql::Statement> statement{ connection->createStatement() };
//res = pstmt->executeQuery("SELECT * FROM test2");
std::unique_ptr<sql::ResultSet> res{ statement->executeQuery(some_query) };
//pstmt->setInt(1, 1);
//pstmt->setString(1, str2);
//res = pstmt->executeQuery();
/* Fetch in reverse = descending order! */
///cikls kur izmantos mysql datu masvu
//res->afterLast();
while (res->next()) {
std::string const FILE_NAME = res->getString("test2col");
string locations2 = ("C:\\Users\\Janis\\Desktop\\TEST2\\");
string txtt = (".txt");
string copy2 = ("copy /-y ");
string space = " ";
string PACIENTI2 = "C:\\PACIENTI\\";
string element = copy2 + locations2 + FILE_NAME + txtt;
//string StartTime = res->getString("StartTime");
//string VisitID = res->getString("VisitID");
//string LastModified = res->getString("LastModified");
//string Id = res->getString("Id");
//string PatientId = res->getString("PatientId");
for (auto& p2 : fs::directory_iterator("C:\\Users\\Janis\\Desktop\\TEST2\\")) {
if (FILE_NAME != p2.path().string()) {
string cmd = element + space + PACIENTI2 + FILE_NAME + txtt;
FILE* pipe = _popen(cmd.c_str(), "r");
cout << cmd << endl;
/*if (pipe == NULL)
{
return;
}
char buffer[128];
std::string result = "";
while (!feof(pipe))
{
if (fgets(buffer, 128, pipe) != NULL)
{
result += buffer;
}
}*/
//std::cout << "Results: " << std::endl << result << std::endl ;
//_pclose(pipe);
}
}
}
//delete res;
//delete pstmt;
//delete con;
}
catch (sql::SQLException& ex) {
std::cerr << "Error occured when connecting to SQL data base: " << ex.what() << "(" << ex.getErrorCode() << ").";
}
}
catch (sql::SQLException& e)
{
///nav implementēts vairāk info
//cout << "# ERR: SQLException in " << __FILE__;
//cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
/* what() (derived from std::runtime_error) fetches error message */
//cout << "# ERR: " << e.what();
//cout << " (MySQL error code: " << e.getErrorCode();
cout << "# ERR: SQLException in " << endl;
}
copy /-y C:\Users\username\Desktop\TEST2\J─ünis.txt C:\PACIENTI\J─ünis.txt
copy /-y C:\Users\username\Desktop\TEST2\Ann─ü.txt C:\PACIENTI\Ann─ü.txt
相反,它应该是
copy /-y C:\Users\Janis\Desktop\TEST2\Jānis.txt C:\PACIENTI\Jānis.txt
copy /-y C:\Users\Janis\Desktop\TEST2\Annā.txt C:\PACIENTI\Annā.txt
我认为您的问题与std::wstring
无关:对于 UTF-8 来说,8 位std::string
应该足够了(使用特殊字符"āàčīēļš"
创建一个简单的std::string
就可以了),而取决于操作系统, std::wstring
是 2 字节 (Windows) 或 4 字节 (Linux)(更多信息在这里和这里)。 毕竟,如果您查看getString
function 您会看到它需要并返回一个sql::SQLString
。 sql::SQLString
class 只是std::string
的简单包装器。
我认为您必须将utf-8 指定为utf-8
的默认字符集:为此,您必须在连接到数据库时指定以下连接选项:
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;
}
当您想使用它或 output 创建文件名到控制台时,现在出现的问题是Windows本身(我之前曾使用 Linux 测试过代码,因此之前没有遇到此问题:) 默认情况下,它使用 ANSI 而不是 UTF-8。 即使您使用 output 之类的āàčīēļš
它也不会 output 正确,无论您是使用std::cout
还是std::wcout
与std::wstring
结合使用。 相反,它将 output ─ü├á─ì─½─ô─╝┼í
。
如果您提取字节
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;
}
它将 output C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1
将其插入字节到 utf8 转换器,例如这个实际上会给你āàčīēļš
。 所以字符串被正确读取,但 Windows 只是没有正确显示它。 以下结合上一节(将utf-8
指定为 MySql 中的默认字符集)应该可以解决您的所有问题:
调用SetConsoleOutputCP(CP_UTF8);
windows.h
程序开始处的 windows.h 将修复控制台 output :
#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(文件的内容不会成为问题,但文件名本身会成为问题。)。 将fstream
中的std::ofstream
与 C++17 库filesystem
中的std::filesystem::u8path
结合使用来解决此问题:
#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; }
为此,您需要将字符串转换为 std::wstring。
#include <codecvt> string FirstName = res->getString("FirstName"); std::wstring firstNameWstring = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(FirstName);
问题是代码的不同部分使用不同的文本数据编码。
由于 MySql 使用utf-8
您可以简单地更改程序以在任何地方使用UTF-8
。 这可以通过构建标志来实现:
cl /source-charset:utf-8 /execution-charset:utf-8 /EHsc YourSources.cpp
/source-charset:utf-8
- 表示您的源文件正在使用utf-8
编码 - 因为您的源可以使用不同的编码确保您使用正确的参数,但强烈建议源代码以通用的标准编码(因此 UTF-8 ),因此来自不同国家的开发人员可以毫无问题地处理代码。/execution-charset:utf-8
- 表示存储在 exactable 中的字符串文字应编码为utf-8
。 现在问题将只是一个控制台( cmd
)。 默认情况下 Windows 控制台使用特定于系统语言设置的编码(继承与旧 DOS 应用程序的兼容性)。 因此,当您强制您的可执行文件默认使用utf-8
控制台时,将错误地打印这些内容。
更改控制台的代码页使其使用utf-8
将解决此问题。
这是我编写的一个测试程序,用于演示如何在 C++ 中处理编码:
#include <iostream>
#include <locale>
#include <exception>
#include <string>
void setupLocale(int argc, const char *argv[])
{
std::locale def{""};
std::locale::global(argc > 1 ? std::locale{argv[1]} : def);
auto streamLocale = argc > 2 ? std::locale{argv[2]} : def;
std::cout.imbue(streamLocale);
std::cin.imbue(streamLocale);
}
void printSeparator()
{
std::cout << "---------\n";
}
void printTestStuff()
{
std::cout << "Wester Europe: āāāčččēēēēßÞÖöñÅÃ\n";
std::cout << "Central Europe: ąĄÓóŁłĘężćźŰűÝýĂă\n";
std::cout << "China: 字集碼是把字符集中的字符编码为指定集合中某一对象\n";
std::cout << "Korean: 줄여서 인코딩은 사용자가 입력한\n";
}
int main(int argc, const char *argv[]) {
try{
setupLocale(argc, argv);
printSeparator();
printTestStuff();
printSeparator();
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
}
当您复制粘贴该程序时,请记住在 UTF-8 中对源代码进行编码(因为我使用广泛的字符来测试大多数其他编码只会失败 - 打开文件时将无法正确显示)。
现在这是我在终端上看到的(复制粘贴):
C:\Users\User\Downloads>cl /source-charset:utf-8 /execution-charset:utf-8 /EHsc encodings.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29336 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
encodings.cpp
Microsoft (R) Incremental Linker Version 14.28.29336.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:encodings.exe
encodings.obj
C:\Users\User\Downloads>chcp
Active code page: 437
C:\Users\User\Downloads>encodings.exe
---------
Wester Europe: Ä?Ä?Ä?Ä?Ä?Ä?Ä"Ä"Ä"Ä"AYAzA-AA±A.Aƒ
Central Europe: Ä.Ä,A"A3Å?Å,Ä~ÄTżÄ╪źŰűA?A½Ä,ă
China: å--é>+碼æ~_æSSå--ç¬▌é>+ä,-çs,å--ç¬▌ç¼-ç ?ä,ºæO╪årsé>+å?^ä,-æY?ä,?å_1象
Korean: ì,ì-¬ì,o ì?,ì½"ë"cì?? ì,¬ìscìz?ê°? ìz.ë ¥ío
---------
C:\Users\User\Downloads>encodings.exe .65001
---------
Wester Europe: aaaccceeeeß_ÖöñÅA
Central Europe: aAOóLlEezczUuYyAa
China: ????????????????????????
Korean: ??? ???? ???? ???
---------
C:\Users\User\Downloads>encodings.exe .65001 .437
---------
Wester Europe: aaaccceeeeß_ÖöñÅA
Central Europe: aAOóLlEezczUuYyAa
China: ????????????????????????
Korean: ??? ???? ???? ???
---------
C:\Users\User\Downloads>encodings.exe .65001 .1250
---------
Wester Europe: aaaccceeeeß_ÖöñÅA
Central Europe: aAOóLlEezczUuYyAa
China: ????????????????????????
Korean: ??? ???? ???? ???
---------
C:\Users\User\Downloads>chcp 1250
Active code page: 1250
C:\Users\User\Downloads>encodings.exe .65001 .1250
---------
Wester Europe: aaačččeeeeß?ÖönAA
Central Europe: ąĄÓóŁłĘężćźŰűÝýĂă
China: ????????????????????????
Korean: ??? ???? ???? ???
---------
C:\Users\User\Downloads>chcp 65001
Active code page: 65001
C:\Users\User\Downloads>encodings.exe
---------
Wester Europe: ÄÄÄÄÄÄēēēēßÞÖöñÅÃ
Central Europe: ąĄÓóÅłĘężćźŰűÃýĂă
China: å—集碼是把å—符集ä¸çš„å—符编ç 为指定集åˆä¸æŸä¸€å¯¹è±¡
Korean: 줄여서 ì¸ì½”ë”©ì€ ì‚¬ìš©ìžê°€ ìž…ë ¥í•œ
---------
C:\Users\User\Downloads>encodings.exe .65001
---------
Wester Europe: āāāčččēēēēßÞÖöñÅÃ
Central Europe: ąĄÓóŁłĘężćźŰűÝýĂă
China: 字集碼是把字符集中的字符编码为指定集合中某一对象
Korean: 줄여서 인코딩은 사용자가 입력한
---------
C:\Users\User\Downloads>encodings.exe .65001 .65001
---------
Wester Europe: āāāčččēēēēßÞÖöñÅÃ
Central Europe: ąĄÓóŁłĘężćźŰűÝýĂă
China: 字集碼是把字符集中的字符编码为指定集合中某一对象
Korean: 줄여서 인코딩은 사용자가 입력한
---------
C:\Users\User\Downloads>
如您所见,如果代码页和编码设置正确,一切正常(不使用 Windows API)。
在我的机器上cmd.exe
无法正确显示亚洲字符,但这只是字体问题,当我将cmd.exe
内容复制到其他程序时,一切都正确显示(以防在我的程序中正确设置编码)。
另请注意,如果无法进行转换,则在执行回退到其他字符时会显示问号(例如,当使用Windows-1250
编码和代码页时, Å
已转换为A
)。
玩一点这个程序我很确定这应该足以给你一个完整的画面。
最重要的:
std::locale::global
定义了主程序使用的编码类型。 这意味着流假定std::string
值以这种方式编码std::iostream::imbue
允许定义 stream 的编码,播种将写入文件的内容。 C4 81 C3 A0 C4 8D C4 AB C4 93 C4 BC C5 A1
,当解释为各种编码时:
utf8: āàčīēļš
latin1: Äà Äīēļš
latin7: ÄĆÄ Ä Ä«ÄļŔ
euckr 훮횪훾카휆캬큄
大概,你想要 utf8(或 utf8mb4)。
连接参数指定客户端的编码。 如果该十六进制字符串来自客户端,则指定 utf8(或 utf8mb4)。
数据库表中的编码可以相同或不同。 这是在模式中指定的; 例如:
CREATE TABLE ...
stuff VARCHAR(99) CHARACTER SET utf8
...
当INSERTing
和SELECTing
时,MySQL 将在客户端的编码和列的编码之间进行转换(如果需要)。
发现:
查看客户端设置:
SHOW VARIABLES LIKE 'char%';
:--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin7 | <--
| character_set_connection | latin7 | <--
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | latin7 | <--
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
查看列的编码: SHOW CREATE TABLE tablename;
.
要查看列中的实际字节:
SELECT col, HEX(col) ...
几乎所有其他技术都容易出错。
请注意,您提到的重音字符都有 UTF-8 十六进制
C3 xx
C4 xx
C5 xx
术语:
“字符集”然后是编码。 示例:latin1、latin7、utf8、utf8mb4。
“排序规则”是指如何对值进行排序和比较。 示例:latin7_general_ci(“ci”是“不区分大小写和不区分重音”的缩写)
(您的连接参数混淆了字符集和排序规则。)
"utf8" 或 "utf8mb3" 是 MySQL 的 3 字节编码。 离开,但仍然适用于所有欧洲语言,以及世界上的大部分 rest。
“utf8mb4”是 MySQL 的 4 字节编码。 等效于 UTF-8。
“UTF-8”是它的世界名称rest。
常见错误:
Visual Studio 允许您更改文件编码。 因此,如果您在变量上键入字符,则应该使用该编码。
在 Visual Studio 中设置选项或以编程方式打开项目属性页对话框。 ... Select 配置属性 > C/C++ > 命令行属性页。 在 Additional Options 中,添加 /utf-8 选项以指定您的首选编码。 选择确定以保存您的更改。 链接https://docs.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8?view=msvc-160
现在对于数据库,请确保您的数据库具有正确的字符集。 https://www.a2hosting.com/kb/developer-corner/mysql/convert-mysql-database-utf-8#:~:text=mysql-,To%20change%20the%20character%20set%20encoding%20to% 20UTF%2D8%20for,q%20at%20the%20mysql%3E%20prompt 。
一旦您对 DB 和 Visual Studio 进行了正确的编码,您就可以保存编辑并从 c ++ 代码中读取这些字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.