Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用c+编码解码的URL+;_C++_Unicode_Character Encoding - Fatal编程技术网

C++ 用c+编码解码的URL+;

C++ 用c+编码解码的URL+;,c++,unicode,character-encoding,C++,Unicode,Character Encoding,我想解码编码的URL。例如,字母ö编码为“%C3%B6”,对应于其十六进制utf-8编码0xc3b6(50102) 现在需要知道如何在控制台上将该值打印为ö或打印到字符串缓冲区中 简单地转换为char、wchar\u t、char16\u t或char32\u t并打印到cout或wcout都不起作用 我得到的最接近的方法是使用它的utf-16表示法0x00f6。下面的代码片段打印 #include <codecvt> #include <iostream> #inclu

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

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

简单地转换为char、wchar\u t、char16\u t或char32\u 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';
}
#包括
#包括
#包括
int main(){
std::wstring_convert;

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

std::string utf8 = "\xc3\xb6"; // or just u8"ö"
printf(utf8);
在Windows中,您必须转换为UTF16。使用
wchar\u t
而不是
char16\u t
,即使
char16\u t
应该是正确的。在Windows中,它们都是每个字符2个字节

您希望将
convert.from_bytes
转换为UTF8,而不是转换为UTF8的
convert.to_bytes

在Windows控制台中打印Unicode是另一个让人头疼的问题。请参阅相关主题

请注意,
std::wstring\u 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;
}
#包括
#包括
#包括
#包括
int main()
{
std::string utf8=“\xc3\xb6”;
std::wstring_convert;
std::wstring utf16=从字节(utf8)转换而来;
MessageBox(0,utf16.c_str(),0,0);
德沃德计数;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE)、utf16.c_str()、utf16.size()、和count,0);
返回0;
}
编码/解码URL

“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;
}
std::string encode\u url(const std::string&s)
{
常量std::字符串安全字符=
“ABCDEFGHIJKLMNOPQRSTUVXYZABDEFGHIJKLMNOPQRSTUVXYZ0123456789-。”;
std::ostringstream oss;
用于(自动c:s){
if(安全字符.查找(c)!=std::string::npos)

oss在POSIX中,您可以直接打印UTF8字符串:

std::string utf8 = "\xc3\xb6"; // or just u8"ö"
printf(utf8);
在Windows中,您必须转换为UTF16。使用
wchar\u t
而不是
char16\u t
,即使
char16\u t
应该是正确的。在Windows中,它们都是每个字符2个字节

您希望将
convert.from_bytes
转换为UTF8,而不是转换为UTF8的
convert.to_bytes

在Windows控制台中打印Unicode是另一个让人头疼的问题。请参阅相关主题

请注意,
std::wstring\u 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;
}
#包括
#包括
#包括
#包括
int main()
{
std::string utf8=“\xc3\xb6”;
std::wstring_convert;
std::wstring utf16=从字节(utf8)转换而来;
MessageBox(0,utf16.c_str(),0,0);
德沃德计数;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE)、utf16.c_str()、utf16.size()、和count,0);
返回0;
}
编码/解码URL

“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;
}
std::string encode\u url(const std::string&s)
{
常量std::字符串安全字符=
“ABCDEFGHIJKLMNOPQRSTUVXYZABDEFGHIJKLMNOPQRSTUVXYZ0123456789-。”;
std::ostringstream oss;
用于(自动c:s){
if(安全字符.查找(c)!=std::string::npos)

oss谢谢你的帮助。这是我的想法。也许它会帮助其他人

#include <iomanip>
#include <iostream>
#include <sstream>

#include <cstdint>

std::string encode_url(const std::string& s) {
  std::ostringstream oss;
  for (std::uint16_t c : s) {
    if (c > 0 && c < 128) {
      oss << static_cast<char>(c);
    }
    else {
      oss << '%' << std::uppercase << std::hex << (0x00ff & c);
    }
  }
  return std::move(oss).str();
} 

int parse_hex(const std::string& s) {
  std::istringstream iss(s);
  int n;
  iss >> std::uppercase >> std::hex >> n;
  return n;
}

std::string decode_url(const std::string& s) {
  std::string result;
  result.reserve(s.size());
  for (std::size_t i = 0; i < s.size();) {
    if (s[i] != '%') {
      result.push_back(s[i]);
      ++i;
    }
    else {
      result.push_back(parse_hex(s.substr(i + 1, 2)));
      i += 3;
    }
  }
  return result;
}
#包括
#包括
#包括
#包括
std::string encode_url(const std::string&s){
std::ostringstream oss;
用于(标准:uint16\U t c:s){
如果(c>0&&c<128){
oss>n;
返回n;
}
std::string decode_url(const std::string&s){
std::字符串结果;
结果:保留(s.大小());
对于(std::size_t i=0;i

仍然有优化的余地,但它是有效的:)

谢谢你的帮助。以下是我的想法。也许它会帮助其他人

#include <iomanip>
#include <iostream>
#include <sstream>

#include <cstdint>

std::string encode_url(const std::string& s) {
  std::ostringstream oss;
  for (std::uint16_t c : s) {
    if (c > 0 && c < 128) {
      oss << static_cast<char>(c);
    }
    else {
      oss << '%' << std::uppercase << std::hex << (0x00ff & c);
    }
  }
  return std::move(oss).str();
} 

int parse_hex(const std::string& s) {
  std::istringstream iss(s);
  int n;
  iss >> std::uppercase >> std::hex >> n;
  return n;
}

std::string decode_url(const std::string& s) {
  std::string result;
  result.reserve(s.size());
  for (std::size_t i = 0; i < s.size();) {
    if (s[i] != '%') {
      result.push_back(s[i]);
      ++i;
    }
    else {
      result.push_back(parse_hex(s.substr(i + 1, 2)));
      i += 3;
    }
  }
  return result;
}
#包括
#包括
#包括
#包括
std::string encode_url(const std::string&s){
std::ostringstream oss;
用于(标准:uint16\U t c:s){
如果(c>0&&c<128){
oss>n;
返回n;
}
std::string decode_url(const std::string&s){
std::字符串结果;
结果:保留(s.大小());
对于(std::size_t i=0;i

仍然有优化的空间,但它是有效的:)

'ö'
大部分是
'\x50\x102'
,因此您不会像现在一样将其放在字符中。@Jarod42是否可以将其放在字符串中?
不在ASCII范围内,因此在这两种情况下都需要超过一个字节。您必须使用像
Lö'
或p这样的宽字符将其打印为字符串而不是字符串char@Jarod4250102是十进制值。它是十六进制的0xC3B6,这是@phuclv的UTF-8表示形式:事实上,我使用了错误的值:-/我的观点主要是多字节字符不适合一个
字符
'ö'
主要是
'\x50\x102'
,因此您不会将其作为一个字符是。@Jarod42是否可以将其放在字符串中?
o
位于ASCII范围之外,因此在任何一个范围中,它都将占用多个字节。您必须使用像
L'ö
这样的宽字符,或者将其作为字符串而不是字符串打印char@Jarod4250102是十进制值。它是十六进制的0xC3B6,是@phuclv:I的UTF-8表示形式ndeed,我使用了错误的值:-/我的观点主要是多字节字符不适合一个
字符
。如果您只想打印,就不需要进行URL编码。URL编码有