首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将服务器响应(std::string)转换为png文件

将服务器响应(std::string)转换为png文件
EN

Stack Overflow用户
提问于 2011-10-10 10:47:40
回答 4查看 2.8K关注 0票数 0

我正在从服务器上获得一个使用boost::asio的响应。结果存储在std::string中。

我希望将这个std::string转换为.png映像并将其写入文件。

我在这方面有很大的麻烦。这是我的代码:

代码语言:javascript
运行
复制
CURL *curl;
CURLcode res;
std::string errorBuffer[CURL_ERROR_SIZE];
std::string url="http://www.google.ie/images/srpr/logo3w.png";
std::string response="";

curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_ENCODING, "gzip");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_to_string);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

res=curl_easy_perform(curl);

curl_easy_cleanup(curl);

现在存储在response中的响应

代码语言:javascript
运行
复制
write_to_binary_file(response.data());

,其中write_to_binary_file是:

代码语言:javascript
运行
复制
void write_to_binary_file(std::string p_Data){
        //std::fstream binary_file("./img.png",std::ios::out|std::ios::binary|std::ios::app);
        //binary_file.write(reinterpret_cast<const char*>(&p_Data),sizeof(std::string));
        //binary_file.close();
        std::ofstream file("img.png", std::ios::binary);
        file.write(p_Data,sizeof(p_Data));
        file.close();
}

现在,如果我对我的C++程序编写的文件执行八进制转储,这与我直接从URL下载文件时得到的八进制转储完全不同。

更新的write_to_binary_file

代码语言:javascript
运行
复制
int write_to_binary_file(const char* p_Data){
        //std::fstream binary_file("./img.png",std::ios::out|std::ios::binary|std::ios::app);
        //binary_file.write(reinterpret_cast<const char*>(&p_Data),sizeof(std::string));
        //binary_file.write(c_str(),sizeof(ring));
        //binary_file.close();
        /*std::ofstream file("img.png", std::ios::binary);
        file.write(p_Data,len);
        file.close();*/
        FILE *fp;
        size_t count;
        const char *str = p_Data;

        fp = fopen("img.png", "w");
        if(fp == NULL) {
                perror("failed to open img.png");
                return EXIT_FAILURE;
        }
        count = fwrite(str, 1, strlen(str), fp);
        printf("Wrote %zu bytes. fclose(fp) %s.\n", count, fclose(fp) == 0 ? "succeeded" : "failed");
        return EXIT_SUCCESS;
}

使用int x=write_to_binary_file(response.c_str());调用

仍然不能为我工作;

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-10-10 10:57:37

代码语言:javascript
运行
复制
binary_file.write(reinterpret_cast<const char*>(&p_Data),sizeof(std::string));

对,这就是为什么reinterpret_cast在许多情况下都很差的原因:它促进了猜测编码。

这是当您丢弃参考资料时,假设您需要在某个地方传递一个指向std::string的指针,并决定编译器的错误消息是错误的。所以,您使用reinterpret_cast来“关闭它”,现在您想知道为什么任何东西都不能正常工作。

想必有人告诉您要“使用std::string”而不是char数组,而且您只是交换了类型名,而不是对实际的区别进行任何研究。

std::string是一个具有各种内部成员的对象,它通常间接地存储它的实际字符串数据(动态的,或者您可能不准确和误导地将其称为“堆上的”);实际上,它完全脱离了您对它存储数据的方式的理解。不管怎样,它不仅仅是一个char数组。

使用它提供的API获取指向char数组的指针,其中包括std::string::data()或可能的std::string::c_str() .和停止猜测编码

此外,我怀疑这是否汇编了:

代码语言:javascript
运行
复制
std::string errorBuffer[CURL_ERROR_SIZE];
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);

您可能希望构造一个具有特定长度的std::string

代码语言:javascript
运行
复制
std::string errorBuffer(CURL_ERROR_SIZE);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &errorBuffer[0]);
// ^ (requires C++11 to be completely safe)

字符串是对象,而不是原始数组!

票数 3
EN

Stack Overflow用户

发布于 2011-10-10 10:53:55

我的第一个猜测是"reinterpret_cast(&p_Data)“正在扰乱您的数据。你为什么要这样投?p_Data.data()或p_Data.c_str()可能是您想要的。

票数 1
EN

Stack Overflow用户

发布于 2011-10-10 15:54:45

对于这样的任务,您可能需要考虑使用SFML,因为它是处理HTTP,并且极大地简化了任务。我个人使用它从一个网站下载.GIF图片。

为了回答你的问题(诚然,我不熟悉boost::asio),您需要考虑的是:

  1. 不要做大量操作(std::string)。string有一个.size()方法。所以response.size();在这里是适用的。
  2. 在处理来自网站的原始数据时,不要使用strlen()、sizeof()或任何使用空尾哨值的方法,因为空值可能发生在原始数据流中的任何地方(它不像文本)。使用std::string的.size()方法。
  3. 如果是原始数据,以二进制模式编写!文本模式将在windows文件中的ctrl+z信号上终止。很可能写不完这份文件。
  4. Base64并不总是适用。不管怎么说,这都是自动化的。
  5. 考虑从提供的URL本身提取文件名。

假设响应是可以接受的,这就是您想要的代码:

代码语言:javascript
运行
复制
FILE * File = NULL;
File = fopen("Image.png","wb"); //Note b for binary mode
if(File == NULL){return 1;} //Error
if(fwrite(response.c_str(),response.size(),1,File) != response.size()) //If there is a mismatch between the amount of data written and the string size, we have an error
{
    perror("File write error occurred"); //Needs errno
    fclose(File);
    return 2;
}

fclose(File);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7711682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档