В POSIX вы можете распечатать строку UTF8 напрямую:
std::string utf8 = "\xc3\xb6"; // or just u8"ö"
printf(utf8);
В Windows вы должны конвертировать в UTF16. Используйте wchar_t
вместо char16_t
, даже если char16_t
считается правильным. Они оба по 2 байта на символ в Windows.
Вы хотите convert.from_bytes
конвертировать из UTF8 вместо convert.to_bytes
, который конвертирует в UTF8.
Печать Unicode в консоли Windows - еще одна головная боль. Смотрите соответствующие темы.
Обратите внимание, что std::wstring_convert
устарела и не имеет замены на данный момент.
#include <iostream>
#include <string>
#include <codecvt>
#include <windows.h>
int main()
{
std::string utf8 = "\xc3\xb6";
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> convert;
std::wstring utf16 = convert.from_bytes(utf8);
MessageBox(0, utf16.c_str(), 0, 0);
DWORD count;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), utf16.c_str(), utf16.size(), &count, 0);
return 0;
}
Кодировка / декодирование URL
«Безопасные символы URL» не нуждаются в кодировании. Все остальные символы, включая символы не ASCII, должны быть закодированы. Пример: * +1021 *
std::string encode_url(const std::string& s)
{
const std::string safe_characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
std::ostringstream oss;
for(auto c : s) {
if (safe_characters.find(c) != std::string::npos)
oss << c;
else
oss << '%' << std::setfill('0') << std::setw(2) <<
std::uppercase << std::hex << (0xff & c);
}
return oss.str();
}
std::string decode_url(const std::string& s)
{
std::string result;
for(std::size_t i = 0; i < s.size(); i++) {
if(s[i] == '%') {
try {
auto v = std::stoi(s.substr(i + 1, 2), nullptr, 16);
result.push_back(0xff & v);
} catch(...) { } //handle error
i += 2;
}
else {
result.push_back(s[i]);
}
}
return result;
}