curl русские символы в url

404
26 ноября 2016, 18:55

каким образом можно открыть курлом сайт с русскими символами в url?

string url("http://usabili.ru/news/2009/09/08/Русский_язык_в_URL.html");
char *output = curl_easy_escape(curl, url.data(), url.length());
if (output) {
url = output;
curl_free(output);
}
url = ReplaceAll(url, "%3A", ":");
url = ReplaceAll(url, "%2F", "/");
curl_easy_setopt(curl, CURLOPT_URL, url); 

Такой вариант не сработал. Если же скопировать url из хрома и поставить его вместо запроса, то все работает

Answer 1
#include <iconv/iconv.h>
#include <errno.h>
#include <string>
#include <vector>
#include <iostream>
#include <curl/curl.h>

using namespace std;
int convertCharset(string inStr, string& outStr, char* fromCharset, char* toCharset, bool clearOutStr = true)
{
    libiconv_t cd;
    cd = libiconv_open(toCharset, fromCharset);
    if (cd == (libiconv_t)(-1))
    {
        throw std::runtime_error("convertCharset: Could not open handle iconv");
    }
    size_t inSize = inStr.size();
    const char* in = inStr.data();

    vector<char> outBuf(1000);
    char* out;
    size_t outSize;
    bool badWord = false;
    while (inSize > 0 && badWord == false)
    {
        errno = 0;
        out = outBuf.data();
        outSize = outBuf.size();
        size_t k = libiconv(cd, &in, &inSize, &out, &outSize);
        if (k == (size_t)-1)
        {
            switch (errno)
            {
            case EINVAL:
                badWord = true;//cannot convert all data, not the full character
                break;
            case E2BIG:
                //out buff small
                break;
            case NULL:
                break;
            default:
                throw std::runtime_error(string("convertCharset: error:") + to_string(errno) + " in byte №" + to_string(inStr.size() - inSize));
            }
        }
        if (clearOutStr) { outStr.clear(); }
        int parsedBytes = outBuf.size() - outSize;
        outStr.append(outBuf.begin(), outBuf.begin() + parsedBytes);
    }
    if (iconv_close(cd) != 0)
        std::runtime_error("convertCharset: Could not close handle iconv");
    return inSize;
}
std::string replaceAll(std::string str, const std::string& from, const std::string& to) {
    size_t start_pos = 0;
    while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
    }
    return str;
}
void main()
{
    string url("http://usabili.ru/news/2009/09/08/Русский_язык_в_URL.html");
    try {
        convertCharset(url, url, "CP1251", "UTF-8");
    }
    catch (std::exception e)
    {
        cout << e.what() << endl;
    }
    CURL *curl = curl_easy_init();
    char *output = curl_easy_escape(curl, url.data(), url.length());
    if (output) {
        url = output;
        curl_free(output);
    }
    url = replaceAll(url, "%3A", ":");
    url = replaceAll(url, "%2F", "/");
    cout << url << endl;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    ...
}

Собственно, в curl_easy_escape нужно посылать UTF-8 изначально.

READ ALSO
Нерекурсивный поиск в глубину

Нерекурсивный поиск в глубину

Как правильно организовать данный алгоритм?

519
Перестал работать getch()

Перестал работать getch()

Перестал работать getch()Компилирует без ошибок, а работать, как следует не хочет, не реагирует на нажатие клавиш

303
как вставить значения получаемые в С++ (qtcharts) в qml в определенной вкладке

как вставить значения получаемые в С++ (qtcharts) в qml в определенной вкладке

Перечитал весь гугл по мвс получаю с помощью методов класса данные, в формате [x,y;x,y;

290
Сжать массив, удалив из него все элементы, величина которых находится в интервале [a,b]. C++

Сжать массив, удалив из него все элементы, величина которых находится в интервале [a,b]. C++

Сжать массив, удалив из него все элементы, величина которых находится в интервале [a,b]Освободившийся в конце массива элементы заполнить нулями

464