c++ - 在 C++ 中编码解码的 url

标签 c++ unicode character-encoding

我想解码编码的 url。例如,字母 ö 被编码为 "%C3%B6",对应于它的十六进制 utf-8 编码 0xc3b6 (50102)。

现在需要知道如何在控制台或字符串缓冲区中将此值打印为 ö。

简单地转换为 char、wchar_t、char16_t 或 char32_t 并打印到 cout 或 wcout 是行不通的。

我得到的最接近的是使用它的 utf-16 表示 0x00f6。以下代码片段打印 ö

#include <codecvt>
#include <iostream>
#include <locale>

int main() {
  std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> convert;
  std::cout << convert.to_bytes(0x00f6) << '\n';
}

我现在需要一种从 0xc3b6 计算 0x00f6 的方法,或者另一种解码 url 的方法。

最佳答案

在 POSIX 中你可以直接打印 UTF8 字符串:

std::string utf8 = "\xc3\xb6"; // or just u8"ö"
printf(utf8);

在 Windows 中,您必须转换为 UTF16。使用 wchar_t 而不是 char16_t,即使 char16_t 应该是正确的。它们在 Windows 中都是每个字符 2 个字节。

您希望 convert.from_bytes 从 UTF8 转换,而不是 convert.to_bytes 转换为 UTF8。

在 Windows 控制台中打印 Unicode 是另一个令人头疼的问题。查看相关主题。

请注意,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 安全字符”不需要编码。应对所有其他字符(包括非 ASCII 字符)进行编码。示例:

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

关于c++ - 在 C++ 中编码解码的 url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54060359/

相关文章:

PHP - 特殊字符(欧元符号)未正确显示(RSS feed/SimplePie)

Java将字符串编码为cp1251

python - python 2.7中的base64编码unicode字符串

c++ - vector.back() 的意外值

c++ - Win64 与 System V ABI (x86_64) : Win64 Skipping registers?

javascript - jquery-textcomplete 不适用于 Unicode 字符,并且缺少空格

c# - 如何去除字符串中的unicode字符

c++ - 为什么使用一个 vs 另一个 : `boost::shared_array` VS `boost::shared_ptr<std::vector>` ?

c++ - 比较字符串时 QtTest 失败,即使它们相同? C++

c++ - LPTSTR 只包含一个字母