我正在从服务器上获得一个使用boost::asio的响应。结果存储在std::string中。
我希望将这个std::string转换为.png映像并将其写入文件。
我在这方面有很大的麻烦。这是我的代码:
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中的响应
write_to_binary_file(response.data());,其中write_to_binary_file是:
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
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());调用
仍然不能为我工作;
发布于 2011-10-10 10:57:37
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() .和停止猜测编码。
此外,我怀疑这是否汇编了:
std::string errorBuffer[CURL_ERROR_SIZE];
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);您可能希望构造一个具有特定长度的std::string:
std::string errorBuffer(CURL_ERROR_SIZE);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &errorBuffer[0]);
// ^ (requires C++11 to be completely safe)字符串是对象,而不是原始数组!
发布于 2011-10-10 10:53:55
我的第一个猜测是"reinterpret_cast(&p_Data)“正在扰乱您的数据。你为什么要这样投?p_Data.data()或p_Data.c_str()可能是您想要的。
发布于 2011-10-10 15:54:45
对于这样的任务,您可能需要考虑使用SFML,因为它是处理HTTP,并且极大地简化了任务。我个人使用它从一个网站下载.GIF图片。
为了回答你的问题(诚然,我不熟悉boost::asio),您需要考虑的是:
假设响应是可以接受的,这就是您想要的代码:
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);https://stackoverflow.com/questions/7711682
复制相似问题