2014-01-19 2 views
0

Мне нужно декодировать URI на C++. Я нашел несколько вопросов об этом, но все они не имеют отношения к кодировке и акцентам UTF-8 (меня интересует точная обработка символов ASCII).Как декодировать URI с символами UTF-8 в C++

Затем я пошел с широко используемой библиотекой, такой как libcurl ... но также не смог обработать кодировку UTF-8. Вот что я делаю

string UriHelper::Decode(const string &encoded) 
{ 
    CURL *curl = curl_easy_init(); 
    int outlength; 
    char *cres = curl_easy_unescape(curl, encoded.c_str(), encoded.length(), &outlength); 
    string res(cres, cres + outlength); 
    curl_free(cres); 
    curl_easy_cleanup(curl); 
    return res; 
} 

Проблема заключается в том, что a%C3%A1e%C3%A9i%C3%ADo%C3%B3u%C3%BA получает декодируется как aáeéiíoóuú, когда он должен быть aáeéiíoóuú. Если я использую a%E1e%E9i%EDo%F3u%FA, он работает отлично.

Есть ли какая-нибудь библиотека, которая может позаботиться о по-разному закодированных URI и справиться с ними?

Спасибо!

ответ

2

Нет ничего плохого в вашем расшифровке. Проблема с печатью расшифрованного URL-адреса. Устройство вывода, которое вы печатаете, настроено на прием строк, закодированных в ISO-8859-1, а не в UTF-8.

Либо настроить устройство вывода на прием строк, закодированных в UTF-8, либо преобразовать декодированный URL из UTF-8 в ISO-8859-1.

1

Как сказал Освальд, проблема не в декодировании ... но с использованием метода, который я использую для отображения строки. Поскольку мне действительно не нужно иметь дело с строками UTF-8, я собираюсь пойти со своим вторым предложением и преобразовать его в ISO-8859-1.

позаимствовали идею (и большая часть кода) этого ответа Is there a way to convert from UTF8 to iso-8859-1?

Для того, чтобы сделать это, я добавил зависимость к Iconv.

Вот мой UriHelper.h

#pragma once 

using namespace std; 

static class UriHelper 
{ 
public: 
    static string Encode(const string &source); 
    static string Decode(const string &encoded); 
}; 

И это мой UriHelper.cpp

#include "UriHelper.h" 
#include <curl/curl.h> 
#include <iconv.h> 

string UriHelper::Encode(const string &source) 
{ 
    CURL *curl = curl_easy_init(); 
    char *cres = curl_easy_escape(curl, source.c_str(), source.length()); 
    string res(cres); 
    curl_free(cres); 
    curl_easy_cleanup(curl); 
    return res; 
} 

string UriHelper::Decode(const string &encoded) 
{ 
    CURL *curl = curl_easy_init(); 
    int outlength; 
    char *cres = curl_easy_unescape(curl, encoded.c_str(), encoded.length(), &outlength); 
    string res(cres, cres + outlength); 
    curl_free(cres); 
    curl_easy_cleanup(curl); 

    //if it's UTF-8, convert it to ISO_8859-1. Based on https://stackoverflow.com/questions/11156473/is-there-a-way-to-convert-from-utf8-to-iso-8859-1/11156490#11156490 
    iconv_t cd = iconv_open("ISO_8859-1", "UTF-8"); 

    const char *in_buf = res.c_str(); 
    size_t in_left = res.length(); 

    char *output = new char[res.length() + 1]; 
    std::fill(output, output + res.length() + 1, '\0'); 
    char *out_buf = &output[0]; 
    size_t out_left = res.length(); 

    do { 
     if (iconv(cd, &in_buf, &in_left, &out_buf, &out_left) == (size_t)-1) { 
      //failed to convert, just return the value received from curl 
      delete[] output; 
      iconv_close(cd); 
      return res; 
     } 
    } while (in_left > 0 && out_left > 0); 

    string outputString(output); 
    delete[] output; 
    iconv_close(cd); 

    return outputString; 
} 
+0

быстрое примечание: Ваш код не является исключением безопасной, ни это MT-сейф –

 Смежные вопросы

  • Нет связанных вопросов^_^