मैं एन्कोडेड यूआरएल को डीकोड करना चाहता हूं। उदाहरण के तौर पर अक्षर ö को इसके हेक्साडेसिमल utf-8 एन्कोडिंग 0xc3b6 (50102) के अनुरूप "%C3%B6" के रूप में एन्कोड किया गया है।

अब यह जानने की जरूरत है कि कंसोल पर या स्ट्रिंग बफर में इस मान को ö के रूप में कैसे प्रिंट किया जाए।

बस 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 की गणना करने का एक तरीका चाहिए या यूआरएल को डीकोड करने के लिए कोई अन्य तरीका चाहिए।

0
sv90 6 जिंदा 2019, 12:48

2 जवाब

सबसे बढ़िया उत्तर

POSIX में आप UTF8 स्ट्रिंग को सीधे प्रिंट कर सकते हैं:

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

विंडोज़ में, आपको यूटीएफ 16 में कनवर्ट करना होगा। char16_t के बजाय wchar_t का प्रयोग करें, भले ही char16_t को सही माना जाए। वे दोनों विंडोज़ में प्रति चरित्र 2 बाइट्स हैं।

आप convert.to_bytes के बजाय convert.from_bytes को UTF8 से रूपांतरित करना चाहते हैं, जो UTF8 में परिवर्तित होता है।

विंडोज कंसोल में यूनिकोड प्रिंट करना एक और सिरदर्द है। प्रासंगिक विषय देखें।

ध्यान दें कि 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;
}

एन्कोडिंग/डिकोडिंग यूआरएल

"यूआरएल सुरक्षित वर्ण" को एन्कोडिंग की आवश्यकता नहीं है। गैर-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;
}
1
Barmak Shemirani 8 जिंदा 2019, 01:21

पूरी सहायताके लिए शुक्रिया। यहाँ मैं क्या लेकर आया हूँ। शायद यह किसी और की मदद करेगा

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

अनुकूलन के लिए अभी भी जगह है लेकिन यह काम करता है :)

1
sv90 7 जिंदा 2019, 16:02