《白话C++》第13章 网络 Page644 获取Bing搜索结果 使用面向对象,封装,改造程序

代码:

#include <curl/curl.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>

using namespace std;

struct ImgDownloader
{
    ImgDownloader(string url)
        : _url(url)
    {
        Init();
    }

    ~ImgDownloader()
    {
        clean();
    }

    int downloadto(string file)
    {
        CURLcode r = curl_easy_perform(_handle);
        if(r != CURLE_OK)
        {
            cerr << curl_easy_strerror(r) << endl;
            cout << "出错了" << endl;
            return -1;
        }

        ofstream ofs(file);
        ofs << _html_data;

        return 0;
    }
    /*libcurl需要的回调函数,必须是纯C的,write_html变成类的成员函数以后,
    编译之后,编译器会偷偷为它插入第一个入参this,可以为write_html加上static,
    变成类的静态成员函数,但是,类的静态成员函数,是不允许访问类的非静态数据的
    (因为非静态数据本质都是this->xxx).这样,write_html使用_html_data那一行,
    编译不过去。怎么办?我们可以借助write_html最后一个入参 void*,
    将this事先传过去,方法是在构造函数中,再加一行:
    curl_easy_setopt(_handle, CURLOPT_WRITEDATA, static_cast<void*>(this));
    然后,在write_html里,就可以再强行转换来
    */
    static size_t write_html(char* data, size_t size, size_t nmemb, void* userdata)
    {
        assert(nmemb != 0);
        //将Init()函数中传递过来this转为ImgDownloader指针
        ImgDownloader* loader = static_cast <ImgDownloader*> (userdata);
        loader->_html_data.append(data, size * nmemb); //html_data后附加 size*nmemb个字节的数据
        return size * nmemb;
    }

    void Init()
    {
        curl_global_init(CURL_GLOBAL_DEFAULT);
        _handle = curl_easy_init();
        curl_easy_setopt(_handle, CURLOPT_URL, _url.c_str());
        curl_easy_setopt(_handle, CURLOPT_WRITEFUNCTION, &write_html);
        //将this对象传给write_html的void* userdata入参
        curl_easy_setopt(_handle, CURLOPT_WRITEDATA, static_cast<void*>(this));
    }

    void clean()
    {
        curl_easy_cleanup(_handle);
        curl_global_cleanup();
    }

    CURL* _handle;
    string _url;
    string _html_data;
};

int main()
{
    cout << "请输入明星姓名的全拼(不要带空格或其他分隔):";
    string name;
    cin >> name;

    string url = "http://cn.bing.com/images/search?q=" + name;

    ImgDownloader downloader(url);

    string file = "./data.html";
    downloader.downloadto(file);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值