【问题标题】:Printing to nowhere with ostream [duplicate]使用ostream打印到无处[重复]
【发布时间】:2011-12-10 17:28:20
【问题描述】:

我想将数据发送到任何地方,我的意思是我不想在控制台或文件中打印数据,但我需要一些std::ostream 对象。该怎么做?

【问题讨论】:

  • 我很确定这是一个骗子,但无法在 atm 上搜索它,因为我在 iPhone 上。

标签: c++ printing stream


【解决方案1】:

我用过:

std::ostream bitBucket(0);

最近没有问题,尽管如果您从某个角度观察它会被标记为存在一些潜在问题(请参阅下面的链接)。

除此之外:据我了解(我也不是完全确定这一点),上面的调用最终会调用 basic_ios::init(0) 并且,因为那是传入 NULL 指针,它将rdstate() 函数返回的流状态设置为badbit 值。

这反过来会阻止流输出更多信息,而只是将其丢弃。

下面的程序展示了它的实际效果:

#include <iostream>

int main (void) {
    std::ostream bitBucket(0);
    bitBucket << "Hello, there!" << std::endl;
    return 0;
}

The page where I got it from 也将此作为可能更清洁的解决方案(稍作修改以删除我上面第一个解决方案的重复):

#include <iostream>

class null_out_buf : public std::streambuf {
    public:
        virtual std::streamsize xsputn (const char * s, std::streamsize n) {
            return n;
        }
        virtual int overflow (int c) {
            return 1;
        }
};

class null_out_stream : public std::ostream {
    public:
        null_out_stream() : std::ostream (&buf) {}
    private:
        null_out_buf buf;
};

null_out_stream cnul;       // My null stream.

int main (void) {
    std::cout << std::boolalpha;

    //testing nul

    std::cout << "Nul stream before: " << cnul.fail() << std::endl;
    cnul << "Goodbye World!" << std::endl;
    std::cout << "Nul stream after: " << cnul.fail() << std::endl;
}

【讨论】:

  • 在构造函数中给0是什么意思?
  • 它(显然,因为我不完全确定内部工作原理)将流状态设置为坏(通过使用 NULL 指针调用 init),我相信它不会再尝试发送任何数据,而只是将其丢弃。对它持粒盐。
【解决方案2】:

最简单的解决方案就是输出到一个未打开的std::ofstream (或任何其他处于错误状态的输出流)。这将导致 流永久处于错误状态。这可能是一个优势 (&lt;&lt; 运算符将跳过格式化),但如果您有任何代码 无法控制对错误的检查,并且如果它们执行某些特定的操作 发生,您可能会遇到问题。

否则,实现一个空流非常简单;唯一的 streambuf 你真正必须重写的函数是overflow。 像下面这样的东西应该可以解决问题:

class NulStreambuf : public std::streambuf
{
    char                dummyBuffer[64];
protected:
    virtual int         overflow( int c )
    {
        setp( dummyBuffer, dummyBuffer + sizeof( dummyBuffer ) ) ;
        return (c == EOF) ? '\0' : c ;
    }
};

(缓冲区会避免一些不必要的虚函数调用。在某些 平台,这有很大的不同。)

然后创建一个使用它的输出流:

class NulOStream : public NulStreambuf, public std::ostream
{
public:
    NulOStream() : std::ostream( this ) {}
};

(使用继承而不是包含,可确保 在传递给ostream 之前,streambuf 已完全构建。 这在实践中通常不是必需的,但标准没有 似乎授权将尚未构建的streambuf 传递给 ostream 的构造函数。)

【讨论】:

    【解决方案3】:

    最简单的解决方案:使用std::stringstream

    #include <sstream>
    #include <iostream>
    
    void func(std::ostream& o){
        o << "blatest\n";
    }
    
    int main(){
        std::stringstream black_hole;
        func(std::cout);
        func(black_hole);
    }
    

    stringstream 将包含输出,但如果你不使用它,它就像从未填充过一样。

    【讨论】:

    • 除了stringstream仍然会分配内存,如果输出很大,这可能是个问题。
    【解决方案4】:

    由于没有人提及,如果是关于抑制std或错​​误输出,您可以简单地关闭相应的文件描述符(例如fclose (stdout)fclose (stderr))。
    这会搞砸一切,包括 printffprintf (stderr, ...)
    所以你确实会继续使用通常的coutcerr,但它们会变成比特桶。

    【讨论】:

      【解决方案5】:

      这里有一些建议:http://bytes.com/topic/c/answers/589209-std-null-stream

      来自该网站的一个很好的答案:

      使用普通的std::fstream,只为写入需要的文件打开 “/开发/空”。它应该可以工作。

      如果你真的想创建自己的流,只需从 basic_ostream 并简单地将您自己的 operator

      #include <streambuf>
      #include <ostream>
      
      template <class cT, class traits = std::char_traits<cT> >
      class basic_nullbuf: public std::basic_streambuf<cT, traits> {
          typename traits::int_type overflow(typename traits::int_type c)
          {
              return traits::not_eof(c); // indicate success
          }
      };
      
      template <class cT, class traits = std::char_traits<cT> >
      class basic_onullstream: public std::basic_ostream<cT, traits> {
      public:
          basic_onullstream():
          std::basic_ios<cT, traits>(&m_sbuf),
          std::basic_ostream<cT, traits>(&m_sbuf)
          {
              init(&m_sbuf);
          }
      
      private:
          basic_nullbuf<cT, traits> m_sbuf;
      };
      
      typedef basic_onullstream<char> onullstream;
      typedef basic_onullstream<wchar_t> wonullstream;
      

      来自http://bytes.com/topic/c/answers/428285-null-ostream

      【讨论】:

        猜你喜欢
        • 2019-08-01
        • 1970-01-01
        • 2012-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多