簡體   English   中英

如何使用libcurl C ++從URL保存XML文件

[英]How to save XML file from url using libcurl c++

如何使用libcurl c ++從URL保存XML文件,以便以后可以使用pugixml加載它。 我已經嘗試過了,但是沒有用

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
    size_t written = fwrite(ptr, size, nmemb, stream);
    return written;
}
...
CURL *curl;
FILE *fp;
CURLcode result;
char *c_url = "http://some_url.xml";
char outfilename[FILENAME_MAX] = "sth.xml";
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
    fp = fopen(outfilename,"wb");
    curl_easy_setopt(curl, CURLOPT_URL, c_url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    result = curl_easy_perform(curl);
}
curl_global_init(CURL_GLOBAL_DEFAULT);
...
curl_easy_cleanup(curl);
curl_global_cleanup();
fclose(fp);

通過將char*設置為const修復錯誤后,如下所示:

char const* c_url = "http://some_url.xml";

您的代碼對我來說很好。

但是,您並不總是想要寫入接收磁盤的數據。 有時,您只想將其保留在內存中以即時使用它。

在這里,我編寫了一個函數,可以將URL的目標下載到std::string ,您可以執行任何操作。 我還使用智能指針使代碼異常安全並且通常更安全。

// write the data into a `std::string` rather than to a file.
std::size_t write_data(void* buf, std::size_t size, std::size_t nmemb,
    void* userp)
{
    if(auto sp = static_cast<std::string*>(userp))
    {
        sp->append(static_cast<char*>(buf), size * nmemb);
        return size * nmemb;
    }

    return 0;
}

// To make the function thread safe you can use a smart pointer to
// hold your CURL session pointer.

// A deleter to use in the smart pointer for automatic cleanup
struct curl_dter{void operator()(CURL* curl) const
    { if(curl) curl_easy_cleanup(curl); }};

// A smart pointer to automatically clean up out CURL session
using curl_uptr = std::unique_ptr<CURL, curl_dter>;

// download the URL into a `std::string`.
std::string get_url(std::string const& url)
{
    std::string data;

    if(auto curl = curl_uptr(curl_easy_init()))
    {
        curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl.get(), CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &data);

        CURLcode ec;
        if((ec = curl_easy_perform(curl.get())) != CURLE_OK)
            throw std::runtime_error(curl_easy_strerror(ec));

    }

    return data;
}

int main()
{
    curl_global_init(CURL_GLOBAL_DEFAULT);

    auto xml = get_url("http://google.co.uk");

    std::cout << xml << '\n';

    curl_global_cleanup();
}

注意:我還添加了CURLOPT_FOLLOWLOCATION選項,以防文檔帶有重定向

如果最后有人感興趣,那么我最終將使用以下代碼:

const char* f = "new_file.xml";
if (curl){
    const char* c_url = "some_url";

    FILE* ofile = fopen(f, "wb");
    if (!ofile) { fprintf(stderr, "Failed to open file: %s\n", strerror(errno)); }

    if (ofile){
        curl_easy_setopt(curl, CURLOPT_URL, c_url);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, ofile);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeData);
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

        curl_easy_perform(curl);

        fclose(ofile);
    }
}
pugi::xml_document doc;
doc.load_file(f);

感謝所有的幫助!

暫無
暫無

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

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