Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何读取图像文件并将其存储在c+中的内存(std::string)+;?_C++_String_Image_File_Binary - Fatal编程技术网

C++ 如何读取图像文件并将其存储在c+中的内存(std::string)+;?

C++ 如何读取图像文件并将其存储在c+中的内存(std::string)+;?,c++,string,image,file,binary,C++,String,Image,File,Binary,今天大部分时间我都在网上搜索,但找不到答案,所以我转向stackoverflow寻求一些建议 基本上,我有一个C++库,它使用CURL执行PUT方法来上传图像文件。现在,这个库接受一个std::字符串作为数据。我的本地磁盘上有图像文件(如jpg、gif、png) 我不关心文件的内容(如中所述,除了将其传递给此库以用于PUT方法之外,我不做任何处理)。如何读取图像文件并将其存储在std::string中?如果文件内容包含空终止符怎么办 我试图添加一些我尝试过的代码,但我是新来的,我不知道如何将我的

今天大部分时间我都在网上搜索,但找不到答案,所以我转向stackoverflow寻求一些建议

基本上,我有一个C++库,它使用CURL执行PUT方法来上传图像文件。现在,这个库接受一个std::字符串作为数据。我的本地磁盘上有图像文件(如jpg、gif、png)

我不关心文件的内容(如中所述,除了将其传递给此库以用于PUT方法之外,我不做任何处理)。如何读取图像文件并将其存储在std::string中?如果文件内容包含空终止符怎么办


我试图添加一些我尝试过的代码,但我是新来的,我不知道如何将我的代码以正确的格式粘贴到这里。任何帮助都将不胜感激。

我能想到的最简单的方法。以二进制模式打开文件,然后将整个内容读入
stringstream

std::ifstream fin("foo.png", std::ios::in | std::ios::binary);
std::ostringstream oss;
oss << fin.rdbuf();
std::string data(oss.str());
std::ifstream-fin(“foo.png”,std::ios::in | std::ios::binary);
std::ostringstream oss;
开放源码软件
这是最短的一个:

std::ifstream fin("foo.png", std::ios::binary);
std::string data((std::istreambuf_iterator<char>(fin)),
                 std::istreambuf_iterator<char>());
std::ifstream-fin(“foo.png”,std::ios::binary);
std::字符串数据((std::istreambuf_迭代器(fin)),
std::istreambuf_迭代器();

更新

类似这样的内容可能用于为回调函数提供信息(我没有测试它):

std::ifstream-fin(“foo.png”,std::ios::binary);
fin.seekg(0,std::ios::end);
...
curl_easy_setopt(m_ctx,CURLOPT_infiresize,fin.tellg());
卷曲设置选项(m_ctx、卷曲读取数据(void*)和fin);
fin.seekg(0,标准::ios::beg);
...
静态大小放入回调(void*ptr、size\t size、size\t nmemb、void*data){
std::ifstream*in=静态广播(数据);
if(in->eof())返回0;
在->读取((字符*)ptr,大小*nmemb);
返回->gcount();
}

这就是库如何进行PUT调用,其中“数据”是作为文件内容传入的字符串

stringstream data_stream.str(data.c_str());
curl_easy_setopt(m_ctx, CURLOPT_UPLOAD,        1L);
curl_easy_setopt(m_ctx, CURLOPT_PUT,           1L);
curl_easy_setopt(m_ctx, CURLOPT_INFILESIZE,    data.length());
curl_easy_setopt(m_ctx, CURLOPT_READFUNCTION,  put_callback);
curl_easy_setopt(m_ctx, CURLOPT_READDATA,      (void *)&data_stream);
curl_easy_setopt(m_ctx, CURLOPT_WRITEFUNCTION, get_callback);
curl_easy_setopt(m_ctx, CURLOPT_WRITEDATA,     (void *)&m_request_response);
下面是curlopt_readfunction的回调函数

static size_t put_callback(void *ptr, size_t size, size_t nmemb, void *data){

  stringstream *output_stream;
  int          retval;

  output_stream = (stringstream *) data;

  if(output_stream->eof()) return 0;

  retval = min(size*nmemb,output_stream->str().size());
  output_stream->read((char *)ptr, retval);

  //return the number of bytes processed 
  return retval;
}

要在这里粘贴代码,只需将所有内容缩进4个空格。或者,粘贴代码,选择它,然后按下如下按钮:
{}
。您还可以通过在文本周围加上一些小东西,将代码与文本内联。我想它们叫回虱子。在我使用过的每个键盘上,它都是在左上角,1键的左边。@Benjamin:在德语键盘布局中,它是在右上角,退格键的左边。:)您还需要按ctrl+alt来获得它。。。在任何情况下,
`
就是这个意思。您使用的库真的需要字符串中的二进制数据吗?你确定这不是它想要的文件名吗?虽然几乎所有平台上的
char
类型都是字节,但使用
std::string
存储二进制数据对我来说似乎是错误的。这正是我所做的。但没有工作,因为它似乎只上传了一部分二进制数据。我昨天在我的代码上尝试了短版本,但这也不起作用。今天我将尝试在这里获取代码,以便在这方面获得更多帮助。至少根据,字符串应该能够存储零字节。是的,字符串可以存储零字节。错误在代码的第一行:
data.c_str()
。这里以零结尾的字符串作为字符指针传递。因此字符串被第一个零字节修剪。要么删除不需要的
c_str()
,要么在回调中使用Benjamin方法中的
stringstream
,或者只需打开
ifstream
,并在回调中使用它(这种方法可以提供更好的性能)。你是对的。我想我需要重写回调函数。我更新了我的帖子,在这方面给你一些帮助。(但我没有亲自测试,因为没有安装curl)。evgeny,谢谢你的更新。但是,我无法打开curl库中的文件。我现在必须传入std::string。我已经测试过通过stringstream,它对我有效。现在,我将回到使用std::string,看看是否可以实现这一点。
std::ifstream fin("foo.png", std::ios::binary);
fin.seekg(0, std::ios::end);
...
curl_easy_setopt(m_ctx, CURLOPT_INFILESIZE,    fin.tellg());
curl_easy_setopt(m_ctx, CURLOPT_READDATA,      (void *)&fin);
fin.seekg(0, std::ios::beg);
...
static size_t put_callback(void *ptr, size_t size, size_t nmemb, void *data){
  std::ifstream* in = static_cast<std::ifstream*>(data);
  if(in->eof()) return 0;
  in->read((char *)ptr, size*nmemb);
  return in->gcount();
}
stringstream data_stream.str(data.c_str());
curl_easy_setopt(m_ctx, CURLOPT_UPLOAD,        1L);
curl_easy_setopt(m_ctx, CURLOPT_PUT,           1L);
curl_easy_setopt(m_ctx, CURLOPT_INFILESIZE,    data.length());
curl_easy_setopt(m_ctx, CURLOPT_READFUNCTION,  put_callback);
curl_easy_setopt(m_ctx, CURLOPT_READDATA,      (void *)&data_stream);
curl_easy_setopt(m_ctx, CURLOPT_WRITEFUNCTION, get_callback);
curl_easy_setopt(m_ctx, CURLOPT_WRITEDATA,     (void *)&m_request_response);
static size_t put_callback(void *ptr, size_t size, size_t nmemb, void *data){

  stringstream *output_stream;
  int          retval;

  output_stream = (stringstream *) data;

  if(output_stream->eof()) return 0;

  retval = min(size*nmemb,output_stream->str().size());
  output_stream->read((char *)ptr, retval);

  //return the number of bytes processed 
  return retval;
}