【问题标题】:how can I convert istream * to string or just print it?如何将 istream * 转换为字符串或仅打印它?
【发布时间】:2013-09-08 16:11:42
【问题描述】:

connector/C++ 的以下函数部分,它返回一个 istream*。如果我只是尝试打印它,它会显示十六进制或内存位置,因为它是 *​​ 类型。

istream *stream = res->getBlob(1);

我试着用这个来阅读和打印它:

    string s; 
    while (getline(*stream, s))
    cout << s << endl; 

但这会因访问冲突而崩溃。还有其他方法可以打印或转换为字符串吗?

getline前stream的值:

  • 流 0x005f3e88 {_Chcount=26806164129143632 } std::basic_istream > *

所以它似乎对我有效。如果失败,我认为它将为 null 或 0

【问题讨论】:

  • 是的,我认为它很好,我在更新中的 watch 变量位置发布了它所说的内容。
  • 我没有看到崩溃的问题:res-&gt;getBlob(1) 和对getline(*stream, s) 的调用之间会发生什么?返回std::istream* 很奇怪,因为它们相对昂贵,如果流不属于resres 指向的东西,这似乎是内存泄漏。
  • res-&gt;getBlob(1)getline(*stream, s) 之间没有任何内容

标签: c++ pointers mysql-connector istream


【解决方案1】:

您可以使用其流缓冲区提取和打印std::istream

std::cout << in->rdbuf();

当然,这会消耗输入,您可能无法再次获得它。如果你想保留内容,你可以写一个std::ostringstream,然后使用str()方法打印内容。或者,您也可以直接从流中构造 std::string,例如:

std::string content{ std::istreambuf_iterator<char>(*in),
                     std::istreambuf_iterator<char>() };

顺便说一句,当您打印流指针时,您实际上使用了void const* 的输出运算符:它打印指针所指的地址。在 C++03 中,您甚至可以通过使用std::istream 读取void* 来恢复相应打印的指针:只要指向的对象没有被删除,您就可以通过这种方式获取指针!然而,在 C++11 中,指针隐藏是被禁止的,以支持将来可能会或可能不会添加到语言中的可选垃圾收集。不过,关于非隐藏指针的保证也有助于成员调试器。

【讨论】:

  • std::cout &lt;&lt; in-&gt;rdbuf(); 行当我用我的 while getline attemp 替换它时仍然崩溃。两者都因访问冲突而以相同的方式崩溃。而且我不太了解您的回答,无法尝试您提到的其他方式
  • @user1397417:我没有看到它实际上崩溃并回答了标题上的问题。另一种方法可能会以几乎相同的方式崩溃。这意味着当您尝试使用它时,流可能已被破坏!在您获得流和使用它之间会发生什么?我您使结果无效,例如,通过移动到下一个元素或保留流以供以后使用。
  • @user1397417:您尝试访问的字段的数据库类型是什么?
  • 我的两个代码块之间没有任何内容。所选列的数据库结构是'english varchar(225) utf8_bin'
  • @user1397417:查看源代码,getBlob() 函数实际上返回一个新的std::istringstream(假设使用已排序,您需要确保在使用后将其删除...)。我可以想象的一件事是,用于 MySQL 连接器和您的构建的标准 C++ 库实际上是不同的:如果您应该验证两者是使用完全相同版本的标准 C++ 库构建的。
【解决方案2】:

您可以在 while 循环中使用 std::getline 函数来显示 istream 中的数据。这是我运行的一个示例,它工作正常:

#include <iostream>
#include <sstream>
#include <istream>
#include <string>

int main()
{

 std::stringstream s1("This is a test string\nWith two lines");
 std::istream s2(s1.rdbuf()); //just creates the istream to start with 

 std::string stt; 
 while(std::getline(s2,stt)) //can also have delimiter in getline 
 {                           
   std::cout<<stt<<std::endl;  
 }

 return 0;
}

运行它并显示:

This is a test string
With two lines

我也试过这个,所以我像你一样使用指向 istream 的指针:

#include <iostream>
#include <sstream>
#include <istream>
#include <string>

int main()
{
  std::stringstream s1("This is a test string\nWith three lines);
  std::istream s2(s1.rdbuf()); //just creates istream to start with 
  std::istream *s3 = &s2; //and use a pointer to istream like code at top

  std::string stt;
  while(std::getline(*s3,stt,'\n')) 
  {                          
    std::cout<<stt<<std::endl; //result.  
  }

  return 0;
}

这段代码运行并给出了与我在不使用指针的情况下得到的结果相同的结果。我无法重现您的错误。所以问题看起来像是你的 istream 的创建(例如 istream *stream = res->getBlob(1);)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 2015-06-26
    • 2015-06-13
    相关资源
    最近更新 更多