【问题标题】:mp3 file corrupted after downloading it from libcurlmp3 文件从 libcurl 下载后损坏
【发布时间】:2020-06-03 08:20:09
【问题描述】:

我正在使用 libcurl 访问 IBM Watson API,我正在下载一个 mp3 文件,但下载的文件已损坏。我期待一个“hello world”消息,但相反,我得到一个损坏的 mp3 文件或地狱的声音。我猜这个错误来自于我将响应转换为const char * 并且它丢失了数据,因为我正在编写二进制数据并且C++ 认为null 关键字是字符串结束符。它输出两个不同的字符串。有什么解决办法吗?

代码:

#include <iostream>
#include <fstream>
#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;
    try
    {
        s->append((char*)contents, newLength);
    }
    catch (std::bad_alloc &e)
    {
        return 0;
    }
    return newLength;
}
std::string CurlGetResponse(std::string url) {
    CURL *curl;
    CURLcode res;

    curl_global_init(CURL_GLOBAL_DEFAULT);

    curl = curl_easy_init();
    std::string response;

    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_USERNAME, "apikey");
        curl_easy_setopt(curl, CURLOPT_PASSWORD, "API Key");

        curl_easy_setopt(curl, CURLOPT_URL, url);

        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, &response);
        res = curl_easy_perform(curl);
        if (res != CURLE_OK)
        {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                curl_easy_strerror(res));
        }
        curl_easy_cleanup(curl);
    }
    return response;
}
int main()
{
    std::string response = CurlGetResponse("url");
    std::cout << response.data();
    std::cout << response;
    std::fstream file;
    file.open("C:\\Users\\maste\\HelloWorld_1.mp3", std::ios::binary);
    file.write(response, sizeof(response));
    file.close();
    return 0;
}

【问题讨论】:

  • 你没有给我们看minimal reproducible example。在main 函数中,response 是什么?如果它是一个std::string 对象,那么问题是sizeof(response) 这是std::string 对象的大小,而不是它包含的字符串的长度。如果response 是一个指针,那么sizeof(response) 是指针的大小,而不是它可能指向的大小。
  • response 是 mp3 的二进制数据(来自 IBM Watson),response 作为字符串返回
  • edit 您的问题包含正确的minimal reproducible examplemain 在哪里定义 response?它的实际类型是什么?请考虑我对sizeof(response) 所说的话。除非 response 是一个实际的编译时 C 样式数组,否则 sizeof 不会像您预期的那样工作。
  • 哦,我明白你的意思了,我忘了添加一行很关键的代码,我太傻了。

标签: c++ libcurl ibm-watson


【解决方案1】:

声明

file.write(response, sizeof(response));

包含两个错误:

  1. 首先它将std::string 对象作为参数传递,但write 需要一个指向要写入的字节的指针。你需要通过例如response.data().

  2. 第二个问题(我在 cmets 中也提到过)是 sizeof(response)std::string 对象本身的大小,而不是它包含的字符串。您需要使用response.size() 来获取实际字符串的大小。

总而言之,语句应如下所示:

file.write(response.data(), response.size());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    相关资源
    最近更新 更多