LibCurl CURLOPT_URL不接受字符串?c++

LibCurl CURLOPT_URL not accepting string? C++

本文关键字:字符串 c++ 不接受 URL CURLOPT LibCurl      更新时间:2023-10-16

基本上我想做的是使用libcurl获取稍微不同的url,例如:

http://foo.com/foo.asp?name=*NAMEHERE*

我想做的是遍历一个名称向量并获取每个名称,例如:

http://foo.com/foo.asp?name=James
然后

http://foo.com/foo.asp?name=Andrew

等等

但是,当我尝试这样做时:

int foo (){
    CURL *curl;
    CURLcode success;
    char errbuf[CURL_ERROR_SIZE];
    int m_timeout = 15;
    if ((curl = curl_easy_init()) == NULL) {
        perror("curl_easy_init");
        return 1;
    }
    std::vector<std::string> names;
    names.push_back("James");
    names.push_back("Andrew");
    for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i){
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, long(m_timeout));
        curl_easy_setopt(curl, CURLOPT_URL, "http://foo.com/foo.asp?name=" + *i);
        curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt");
        curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt");
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1L);
    }
    if ((success = curl_easy_perform(curl)) != 0) {
        fprintf(stderr, "%s: %sn", "curl_easy_perform", errbuf);
        return 1;
    }
    curl_easy_cleanup(curl);
    return 0;
}

显示错误:

不能通过可变函数传递非平凡类型的对象'std::__1::basic_string';调用将在运行时中止

这一行:

curl_easy_setopt(curl, CURLOPT_URL, "http://foo.com/foo.asp?name=" + *i);

因为+ *i .

我想做的是可能的吗?有解决办法吗?

编辑:谢谢你的回答,但出于某种原因,当我运行这个时,它只得到vector中最后一个字符串的网站,它忽略了其他的。在我的例子中,它跳过James直接进入Andrew。为什么会这样呢?

CURLOPT_URL传递给curl_easy_setopt的参数需要是char *而不是std::string。您可以通过调用c_str成员函数从std::string获得const char *:

std::string url = "http://foo.com/foo.asp?name=" + *i;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

对于将来在这里结束的任何人,如果你还没有看过curl手册,请看看。还有一本网上的书

curl_easy_setopt的文档说你需要阅读一个特定的选项来知道使用什么参数类型。

所有选项都是用一个选项后跟一个参数来设置的。该形参可以是long型、函数指针、对象指针或curl_off_t ,这取决于特定选项的期望。仔细阅读本手册,因为错误的输入值可能会导致libcurl表现不佳!

CURLOPT_URL的文档准确地说明了参数类型需要是什么。

传递一个指向要使用的URL的指针。参数应该是一个char *到一个以零结尾的字符串,必须以以下格式进行url编码:

方案://主机:港口/路径

由于某种原因,当我运行这个时,它只得到向量中最后一个字符串的网站,而忽略了其他字符串。在我的例子中,它跳过James,直接进入Andrew。为什么会这样呢?

您正在循环配置curl对象的所有名称,在每次循环迭代中使用不同的名称,然后您仅在循环完成后调用curl_easy_perform(),因此它将仅检索配置的最后一个名称。您需要将调用移动到循环内部的curl_easy_perform():

for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i)
{
    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, long(m_timeout));
    string url = "http://foo.com/foo.asp?name=" + *i;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt");
    curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt");
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1L);
    success = curl_easy_perform(curl);
    if (success != 0) {
        fprintf(stderr, "%s: %sn", "curl_easy_perform", errbuf);
        // handle the error as needed...
        continue;
    }
    // use the downloaded content as needed...
}