簡體   English   中英

如何在C ++中使用UTF-8字符解碼URI

[英]How to decode an URI with UTF-8 characters in C++

我需要在C ++中解碼URI。 我發現了幾個有關此問題,但它們都無法處理UTF-8編碼和重音(我對准確處理ASCII字符很感興趣)。

然后,我使用了廣泛使用的庫,例如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並處理它們的庫?

謝謝!

您的解碼沒有錯。 問題是打印解碼的URL。 打印到的輸出設備配置為接受以ISO-8859-1(而不是UTF-8)編碼的字符串。

將輸出設備配置為接受以UTF-8編碼的字符串,或者將解碼的URL從UTF-8轉換為ISO-8859-1。

正如Oswald所說的,問題不在於解碼...而是我用來顯示字符串的方法。 因為我真的不需要處理UTF-8字符串,所以我將繼續他的第二個建議,並將其轉換為ISO-8859-1。

從此答案中借用了這個想法(以及大部分代碼)。 是否有辦法將UTF8轉換為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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM