2009-10-28 13 views
49

Sto costruendo un'applicazione (su Windows utilizzando Dev-C++) e voglio che scarichi un file. Lo sto facendo usando libcurl (ho già installato il codice sorgente usando packman). Ho trovato un esempio funzionante (http://siddhantahuja.wordpress.com/2009/04/12/how-to-download-a-file-from-a-url-and-save-onto-local-directory-in-c-using-libcurl/) ma non chiude il file al termine del download. Vorrei che qualcuno fornisse un esempio su come scaricare un file, in c o C++. Grazie in anticipo!Scarica il file usando libcurl in C/C++

+6

ho voluto votare fino alla tua domanda, ma la risposta fatte non me. –

risposta

179

L'esempio che si sta utilizzando è errato. Vedere la pagina man per easy_setopt. Nell'esempio write_data utilizza il proprio FILE, * outfile e non l'fp specificato in CURLOPT_WRITEDATA. Ecco perché la chiusura di fp causa problemi: non è nemmeno aperta.

Questo è più o meno quello che dovrebbe essere simile (senza libcurl disponibile qui per provare)

#include <stdio.h> 
#include <curl/curl.h> 
/* For older cURL versions you will also need 
#include <curl/types.h> 
#include <curl/easy.h> 
*/ 
#include <string> 

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) { 
    size_t written = fwrite(ptr, size, nmemb, stream); 
    return written; 
} 

int main(void) { 
    CURL *curl; 
    FILE *fp; 
    CURLcode res; 
    char *url = "http://localhost/aaa.txt"; 
    char outfilename[FILENAME_MAX] = "C:\\bbb.txt"; 
    curl = curl_easy_init(); 
    if (curl) { 
     fp = fopen(outfilename,"wb"); 
     curl_easy_setopt(curl, CURLOPT_URL, url); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 
     res = curl_easy_perform(curl); 
     /* always cleanup */ 
     curl_easy_cleanup(curl); 
     fclose(fp); 
    } 
    return 0; 
} 

Aggiornamento: come suggerito da @rsethc types.h e easy.h non sono presenti nelle versioni attuali cURL più.

+1

Ho provato questo (sotto OSX), ma sto ottenendo: avvertimento: deprecato conversione da stringa costante a 'char *' simboli non definiti: "___gxx_personality_v0", si fa riferimento da: _main in ccHRyU1T.o WRITE_DATA (void *, unsigned long, unsigned long, __sFILE *) in ccHRyU1T.o CIE in ccHRyU1T.o ld: simbolo (i) non trovato collect2: ld restituito 1 stato di uscita Aiuto per favore !! – TCB13

+0

@ TCB13 il programma che ho scritto è C, non C++. Ricompila come C e i problemi dovrebbero andare entrambi via. – fvu

+8

+1 perché credo che l'OP dovrebbe averlo selezionato come risposta, perché il codice è praticamente lo stesso. – alexy13

14

Solo per chi è interessato, è possibile evitare di scrivere la funzione personalizzata passando NULL come ultimo parametro (se non si intende eseguire un'ulteriore elaborazione dei dati restituiti).
In questo caso viene utilizzata la funzione interna predefinita.

dettagli
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTWRITEDATA

Esempio

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

int main(void) 
{ 
    CURL *curl; 
    FILE *fp; 
    CURLcode res; 
    char *url = "http://stackoverflow.com"; 
    char outfilename[FILENAME_MAX] = "page.html"; 
    curl = curl_easy_init();                                                               
    if (curl) 
    { 
     fp = fopen(outfilename,"wb"); 
     curl_easy_setopt(curl, CURLOPT_URL, url); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 
     res = curl_easy_perform(curl); 
     curl_easy_cleanup(curl); 
     fclose(fp); 
    } 
    return 0; 
} 
+0

Questo non funziona su Windows. Su Windows è necessario impostare CURLOPT_WRITEFUNCTION non-null altrimenti si verifica un arresto anomalo. Vedere https://curl.haxx.se/libcurl/c/CURLOPT_WRITEDATA.html –

+0

@PhilRosenberg bene questo sembra sfortunato, poiché qui https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html # DESCRIZIONE afferma chiaramente: "Impostare questa opzione su NULL per ottenere la funzione di default interna utilizzata al posto del callback." Quindi "Se si sta utilizzando libcurl come DLL win32, è necessario utilizzare CURLOPT_WRITEFUNCTION se si imposta questa opzione o sperimenterai arresti anomali. " non dovrebbe avere alcun effetto, poiché dovrebbe essere utilizzata di nuovo la funzione interna. – Petar