C : 重定向 STDOUT

新手上路,请多包涵

在我的应用程序中,我想将通常会转到 stdout 流的输出重定向到我定义的函数。我读到您 可以 将 stdio 重定向到文件,那么为什么不重定向到函数呢?

例如:

 void MyHandler( const char* data );

//<<Magical redirection code>>

printf( "test" );
std::cout << "test" << std::endl;

//MyHandler should have been called with "test" twice, at this point

  • 我怎样才能实现这种/类似的行为?

原文由 Charx 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 861
1 个回答

另一种选择是将处理程序类调用放入继承的 streambuf 类中。我需要将 cout 重定向到可能有用的对话框中的 Win GUI 编辑控件。这是课程代码:

 //-------------------------------- DlgStringbuf Definition -----------------------
class DlgStringbuf : public std::stringbuf
{
public:
  DlgStringbuf(void) : _hwndDlg(NULL), _editControlID(0), _accum(""), _lineNum(0) {}

  void SetDlg(HWND dlg, int editControlID)
    { _hwndDlg = dlg; _editControlID = editControlID; }
  void Clear(void)
    { _accum.clear(); _lineNum = 0; }

protected:
  virtual std::streamsize xsputn(const char* s, std::streamsize num)
  {
    std::mutex m;
    std::lock_guard<std::mutex> lg(m);

    // Prepend with the line number
    std::string str(s, (const uint32_t)num);
    str = std::to_string(_lineNum) + ": " + str + "\r\n";

    // Accumulate the latest text to the front
    _accum = str + _accum;

    // Write to the Win32 dialog edit control.
    if(_hwndDlg != NULL)
      SetDlgItemTextW(_hwndDlg, _editControlID, (LPCWSTR)(std::wstring(_accum.begin(), _accum.end())).c_str());

    _lineNum++;
    return(num);
  }//end xsputn.

private:
  std::string     _accum;
  HWND            _hwndDlg;
  int             _editControlID;
  uint32_t        _lineNum;

};//end DlgStringbuf.

//-------------------------------- DlgStream Definition ------------------------------
class DlgStream : public std::ostream
{
public:
  DlgStream(void) : std::ostream(&_sbuff) {}

  void SetDlg(HWND dlg, int editControlID)
    { _sbuff.SetDlg(dlg, editControlID); }

  void Clear(void)
    { _sbuff.Clear(); }

private:
  DlgStringbuf  _sbuff;
};

…在 WinMain 中,创建对话框及其编辑控件之后的某个位置:

   // Redirect all cout usage to the activity dlg box.
  // Save output buffer of the stream - use unique pointer with deleter that ensures to restore
  // the original output buffer at the end of the program.
  auto del = [&](streambuf* p) {  cout.rdbuf(p); };
  unique_ptr<streambuf, decltype(del)> origBuffer(cout.rdbuf(), del);

  // Redirect the output to the dlg stream.
  _dlgStream.SetDlg(hwndActivityDlg, IDC_EDIT_ACTIVITY);
  _dlgStream.copyfmt(cout);
  cout.rdbuf(_dlgStream.rdbuf());

  cout << "this is from cout";

原文由 Keith 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题