0

I'm trying to use libcurl with C++ to download a single image file to my Ubuntu machine.

I tried copying and pasting the simple example shown in this question: Download file using libcurl in C/C++

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

using namespace std;

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;
    const char *url = "https://i.imgur.com/mWj0yzI.jpg";
    char outfilename[FILENAME_MAX] = "/home/my_username/test.jpg";
    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;
}

I expected it to download the image file and save it as "test.jpg" on my machine. However, when I run this program, "test.jpg" is 0 bytes in size. Apparently the image didn't write to the file for some reason.

What am I doing wrong?

kvars
  • 31
  • 3
  • 3
    You need to do something with `res` - currently you have no idea why your code fails, use the return value from curl_easy_perform to start diagnosing. Same if curl init failed - you don't print any diagnostics. – Mat Aug 13 '19 at 17:44
  • Are you sure that `fopen` did succeed? Study more carefully the documentation of `libcurl` (and of `fwrite`) and read [*How to debug small programs*](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). Consider using `fflush` – Basile Starynkevitch Aug 13 '19 at 17:46
  • Thanks for the suggestion, I added the line `cout << curl_easy_strerror(res) << endl;` right after storing `res`, and it said `No error`. I'm not sure what I should do to diagnose the init, however. – kvars Aug 13 '19 at 17:48
  • I added `fflush(fp);` right before the cleanup steps, there was no change in the behavior. – kvars Aug 13 '19 at 17:51
  • Consider using a debugger to step through your code line by line. See also: https://stackoverflow.com/q/25385173/5910058 – Jesper Juhl Aug 13 '19 at 17:54

1 Answers1

1

Your link does not point to an existing file. With a correct link it works for me. Try this:

const char *url = "https://i.imgur.com/oRtvmGT.jpg";

Rick Pat
  • 789
  • 5
  • 14
  • Thanks, this worked! How bizarre; when I copy and paste the link from my own code into a browser, an image does appear. Do you know why C++ thinks that the file doesn't exist? – kvars Aug 13 '19 at 17:55
  • when i go to the link i get redirected to `https://i.imgur.com/removed.png` which is an image. I guess curl will not let itself be redirected to a different file and download it, which is probably a good thing, from a security standpoint. :) – Rick Pat Aug 13 '19 at 18:01
  • 1
    Ah, I figured it out! My browser had saved the image in a cache, so when I went to the link, I got the old image. Going to the link on incognito does give removed.png... how vexing that the image was removed in the minute or two between me first accessing it and trying to download it :P – kvars Aug 13 '19 at 18:03