2010-02-24 43 views
64

Tôi muốn lưu trữ kết quả của hàm curl này trong một biến, làm thế nào tôi có thể làm như vậy?C libcurl lấy đầu ra thành một chuỗi

#include <stdio.h> 
#include <curl/curl.h> 

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 

    curl = curl_easy_init(); 
    if(curl) { 
    curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); 
    res = curl_easy_perform(curl); 

    /* always cleanup */ 
    curl_easy_cleanup(curl); 
    } 
    return 0; 
} 

cảm ơn, tôi giải quyết nó như thế này:

#include <stdio.h> 
#include <stdlib.h> 
#include <curl/curl.h> 

function_pt(void *ptr, size_t size, size_t nmemb, void *stream){ 
    printf("%d", atoi(ptr)); 
} 

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 
    curl = curl_easy_init(); 
    if(curl) { 
    curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_pt); 
    curl_easy_perform(curl); 
    curl_easy_cleanup(curl); 
    } 
    system("pause"); 
    return 0; 
} 
+1

Chỉ cần chỉ ra giải pháp của bạn trong function_pt() bạn đang chuyển đổi chuỗi trong ptr thành số nguyên để chuyển đổi chuỗi đó thành chuỗi ở đầu ra. Bạn có thể xuất chuỗi trực tiếp (và xem câu trả lời đầy đủ). – zzz

+0

đây là liên kết đến ví dụ cURL http://curl.haxx.se/libcurl/c/getinmemory.html – lafferc

+0

'CURLcode res;' không được sử dụng – fnc12

Trả lời

82

Bạn có thể thiết lập một chức năng gọi lại để nhận những phần dữ liệu đến sử dụng curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);

Các callback sẽ mất một người dùng xác lập luận rằng bạn có thể đặt sử dụng curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)

Dưới đây là một đoạn mã mà qua một bộ đệm struct string {*ptr; len} để chức năng gọi lại và phát triển bộ đệm đó trên mỗi cuộc gọi bằng cách sử dụng realloc().

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <curl/curl.h> 

struct string { 
    char *ptr; 
    size_t len; 
}; 

void init_string(struct string *s) { 
    s->len = 0; 
    s->ptr = malloc(s->len+1); 
    if (s->ptr == NULL) { 
    fprintf(stderr, "malloc() failed\n"); 
    exit(EXIT_FAILURE); 
    } 
    s->ptr[0] = '\0'; 
} 

size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s) 
{ 
    size_t new_len = s->len + size*nmemb; 
    s->ptr = realloc(s->ptr, new_len+1); 
    if (s->ptr == NULL) { 
    fprintf(stderr, "realloc() failed\n"); 
    exit(EXIT_FAILURE); 
    } 
    memcpy(s->ptr+s->len, ptr, size*nmemb); 
    s->ptr[new_len] = '\0'; 
    s->len = new_len; 

    return size*nmemb; 
} 

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 

    curl = curl_easy_init(); 
    if(curl) { 
    struct string s; 
    init_string(&s); 

    curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 
    res = curl_easy_perform(curl); 

    printf("%s\n", s.ptr); 
    free(s.ptr); 

    /* always cleanup */ 
    curl_easy_cleanup(curl); 
    } 
    return 0; 
} 
+0

Câu trả lời rất hay. Tôi có tất cả các em trong chuỗi. Yipee! –

+1

Rất đẹp. Thậm chí đẹp hơn nếu tất cả những 'size_t' (bên cạnh' len' chính nó) sẽ được khai báo 'const'. – alk

7

Từ đọc hướng dẫn ở đây: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html tôi nghĩ rằng bạn cần một số cuộc gọi đến CURL_SETOPT, đầu tiên là các URL mà bạn muốn xử lý, thứ hai là một cái gì đó như:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_ptr); 

đâu function_ptr phù hợp với chữ ký này:

size_t function(void *ptr, size_t size, size_t nmemb, void *stream) 

Điều gì xảy ra ở đây là bạn biểu thị hàm gọi lại mà libcurl sẽ gọi khi nó có một số đầu ra để viết từ bất kỳ chuyển nào bạn đã gọi. Bạn có thể làm cho nó tự động ghi vào một tập tin, hoặc vượt qua nó một con trỏ đến một hàm mà sẽ xử lý đầu ra chính nó. Sử dụng chức năng này, bạn sẽ có thể lắp ráp các chuỗi đầu ra khác nhau thành một mảnh và sau đó sử dụng chúng trong chương trình của bạn.

Tôi không chắc chắn các tùy chọn khác mà bạn có thể phải đặt/điều gì khác ảnh hưởng đến cách bạn muốn ứng dụng của mình hoạt động, vì vậy hãy xem qua trang đó.

21

Câu trả lời sau là cách C++ để làm điều đó, với std::string, thay vì chuỗi bị chấm dứt null. Nó vẫn sử dụng một hàm gọi lại (không có cách nào xung quanh nó), mà còn xử lý lỗi phân bổ bằng try/catch.

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

size_t CurlWrite_CallbackFunc_StdString(void *contents, size_t size, size_t nmemb, std::string *s) 
{ 
    size_t newLength = size*nmemb; 
    size_t oldLength = s->size(); 
    try 
    { 
     s->resize(oldLength + newLength); 
    } 
    catch(std::bad_alloc &e) 
    { 
     //handle memory problem 
     return 0; 
    } 

    std::copy((char*)contents,(char*)contents+newLength,s->begin()+oldLength); 
    return size*nmemb; 
} 
int main() 
{ 
    CURL *curl; 
    CURLcode res; 

    curl_global_init(CURL_GLOBAL_DEFAULT); 

    curl = curl_easy_init(); 
    std::string s; 
    if(curl) 
    { 

     curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); 

     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //only for https 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); //only for https 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 
     curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); //remove this to disable verbose output 


     /* Perform the request, res will get the return code */ 
     res = curl_easy_perform(curl); 
     /* Check for errors */ 
     if(res != CURLE_OK) 
     { 
      fprintf(stderr, "curl_easy_perform() failed: %s\n", 
        curl_easy_strerror(res)); 
     } 

     /* always cleanup */ 
     curl_easy_cleanup(curl); 
    } 

    std::cout<<s<<std::endl; 

    std::cout<< "Program finished!" << std::endl; 
} 
+1

Làm việc tốt cho tôi. Dễ dàng và ngắn hơn câu trả lời ở trên ... !!! – mbaros

Các vấn đề liên quan