【问题标题】:creating an ostream创建一个 ostream
【发布时间】:2009-02-07 20:32:31
【问题描述】:

出于教育原因,我正在尝试创建一个 c++ ostream。我的测试将创建一个 ostream,其行为类似于 ofstream,除了写入文件而不是写入双端队列或向量容器。

【问题讨论】:

  • 也许你可以改进你的问题来提出一个实际的问题。

标签: c++ std ostream


【解决方案1】:

正如你所说,对于教育来说,我会告诉你我会如何做这样的事情。否则,stringstream 真的是要走的路。

听起来您想创建一个 streambuf 实现,然后写入向量/双端队列。像这样的东西(从我的另一个答案复制targeted a /dev/null stream):

template<typename Ch, typename Traits = std::char_traits<Ch>,
         typename Sequence = std::vector<Ch> >
struct basic_seqbuf : std::basic_streambuf<Ch, Traits> {
     typedef std::basic_streambuf<Ch, Traits> base_type;
     typedef typename base_type::int_type int_type;
     typedef typename base_type::traits_type traits_type;

     virtual int_type overflow(int_type ch) {
         if(traits_type::eq_int_type(ch, traits_type::eof()))
             return traits_type::eof();
         c.push_back(traits_type::to_char_type(ch));
         return ch;
     }

    Sequence const& get_sequence() const {
        return c;
    }
protected:
    Sequence c;
};

// convenient typedefs
typedef basic_seqbuf<char> seqbuf;
typedef basic_seqbuf<wchar_t> wseqbuf;

你可以这样使用它:

seqbuf s;
std::ostream os(&s);
os << "hello, i'm " << 22 << " years old" << std::endl;
std::vector<char> v = s.get_sequence();

如果你想要一个双端队列作为序列,你可以这样做:

typedef basic_seqbuf< char, char_traits<char>, std::deque<char> > dseq_buf;

或类似的东西...好吧,我还没有测试过。但也许这也是一件好事 - 所以如果它仍然包含错误,您可以尝试修复它们。

【讨论】:

  • 感谢代码 sn-p。虽然stackoverflow.com/questions/760301/… 这里使用了相同的方法来禁用输出,但我想知道进行每个字符处理是否是最佳选择(因为overflow 一次需要一个字符)还是有任何方法可以与basic_streambuf::sputn(const char* s, streamsize n) 相交?跨度>
【解决方案2】:

使用 std::stringstream

#include <iostream>
#include <sstream>
int main()
{
    std::stringstream   s;
    s << "Plop" << 5;

    std::cout << s.str();
}

【讨论】:

  • 虽然它会写入一个字符串,但它可能打算将“5”写入一个二进制整数。
  • @JeroenBollen:使用已经存在的东西更容易做到这一点:stackoverflow.com/a/5146138/14065std::cout &lt;&lt; std::bitset&lt;4&gt;(5) &lt;&lt; "\n";
【解决方案3】:

我只想说,您不必为此编写类似 ostream 的类。您可以使用适配器来实现您的目标。

例如,这段代码从 istream 中读取并将每个元素插入到一个向量中:

vector<string> V;
copy(istream_iterator<string>(cin), 
     istream_iterator<string>(), 
     back_inserter(V)); 

【讨论】:

    【解决方案4】:

    如果没有更多关于您想要做什么的详细信息,很难说得太具体,但您不想创建新的 ostream。您要做的是创建一个新类型的 streambuf,并使用现有的 ostream。

    最简单的做法是从 std::basic_filebuf 继承,并重载 sync() 和 overflow() 方法以将元素添加到您的数据结构中。

    【讨论】:

      猜你喜欢
      • 2017-07-16
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多