صحيح الإفراط في تحميل stringbuf ليحل محل cout في ملف MEX MATLAB

StackOverflow https://stackoverflow.com/questions/243696

سؤال

وماثووركس حاليا لا يسمح لك باستخدام cout من ملف مكس عند سطح المكتب MATLAB مفتوح لأنهم إعادة توجيه المعياري. الحل ضعها الراهن هو توفير وظيفة، mexPrintf، التي يطلبونها كنت تستخدم بدلا من ذلك . بعد غوغلينغ حول قليلا، وأعتقد أنه من الممكن تمديد الطبقة std::stringbuf أن تفعل ما أحتاج. وهنا ما لدي حتى الآن. هذا هو قوي بما فيه الكفاية، أم أن هناك أساليب أخرى أحتاج الزائد أو طريقة أفضل للقيام بذلك؟ (أبحث عن قابلية في بيئة UNIX العامة والقدرة على استخدام std::cout كالمعتاد إذا لم يتم ربط هذا الرمز ضد تنفيذ المكسيك)

class mstream : public stringbuf {
public:
  virtual streamsize xsputn(const char *s, std::streamsize n) 
  {
mexPrintf("*s",s,n);
return basic_streambuf<char, std::char_traits<char>>::xsputn(s,n);
  }
}; 

mstream mout;
outbuf = cout.rdbuf(mout.rdbuf());    
هل كانت مفيدة؟

المحلول

وأنت لا تريد حقا أن الزائد std::stringbuf، وتريد أن تفرط std::streambuf أو std::basic_streambuf (إذا كنت ترغب في دعم أنواع الحرف متعددة)، كما تحتاج إلى تجاوز أسلوب تجاوز أيضا.

ولكن أعتقد أيضا تحتاج إلى إعادة التفكير في حل لمشكلتك.

وcout هو مجرد ostream، لذلك إذا كان كل الفصول / وظائف يأخذ على ostream ثم يمكنك تمرير في أي شيء تريد. مثلا cout، ofstream، الخ

وإذا كان هذا صعبا للغاية بعد ذلك من شأنه أن يخلق نسختي الخاصة من cout، ربما دعا mycout التي يمكن تعريفها في أي وقت مترجم أو الوقت وقت التشغيل (اعتمادا على ما تريد القيام به).

قد يكون هناك حل بسيط:

#include <streambuf>
#include <ostream>

class mystream : public std::streambuf
{
public:
    mystream() {}

protected:
    virtual int_type overflow(int_type c)
    {
        if(c != EOF)
        {
            char z = c;
            mexPrintf("%c",c);
            return EOF;
        }
        return c;
    }

    virtual std::streamsize xsputn(const char* s, std::streamsize num)
    {
        mexPrintf("*s",s,n);
        return num;
    }
};

class myostream : public std::ostream
{
protected:
    mystream buf;

public:
    myostream() : std::ostream(&buf) {}
};

myostream mycout;

والنسخة cout يمكن أن يكون مجرد:

typedef std::cout mycout;

وهناك نسخة وقت التشغيل هو أكثر قليلا من العمل ولكن قابلة للتنفيذ بسهولة.

نصائح أخرى

وشين، شكرا جزيلا لمساعدتكم. وهنا قال لي تنفيذ العمل النهائي.

class mstream : public std::streambuf {
public:
protected:
  virtual std::streamsize xsputn(const char *s, std::streamsize n); 
  virtual int overflow(int c = EOF);
}; 

...

std::streamsize 
mstream::xsputn(const char *s, std::streamsize n) 
{
  mexPrintf("%.*s",n,s);
  return n;
}

int 
mstream::overflow(int c) 
{
    if (c != EOF) {
      mexPrintf("%.1s",&c);
    }
    return 1;
}

...

// Replace the std stream with the 'matlab' stream
// Put this in the beginning of the mex function
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout); 

...

// Restore the std stream buffer 
std::cout.rdbuf(outbuf); 

ولقد تغيرت التنفيذ النهائي للOP في قليلا، مضيفا منشئ والمدمر. إنشاء كائن من هذه الفئة تلقائيا يستبدل عازلة تيار في std::cout، وعندما ينتقل الكائن خارج النطاق، يتم استعادة المخزن المؤقت التيار الأصلي. RAII!

class mxstreambuf : public std::streambuf {
   public:
      mxstreambuf() {
         stdoutbuf = std::cout.rdbuf( this );
      }
      ~mxstreambuf() {
         std::cout.rdbuf( stdoutbuf );
      }
   protected:
      virtual std::streamsize xsputn( const char* s, std::streamsize n ) override {
         mexPrintf( "%.*s", n, s );
         return n;
      }
      virtual int overflow( int c = EOF ) override {
         if( c != EOF ) {
            mexPrintf( "%.1s", & c );
         }
         return 1;
      }
   private:
      std::streambuf *stdoutbuf;
};

لاستخدام المخزن المؤقت تيار في ملف MEX، ببساطة:

mxstreambuf mout;
std::cout << "Hello World!\n";

... ولا تقلق بشأن نسيان أي شيء.

وcout هو دفق إخراج حرف معين. إذا كنت ترغب في cout أن يكتب إلى ملف، استخدم fstream ، ولا سيما في ofstream . لديهم نفس الواجهة التي cout يقدمها. بالإضافة إلى ذلك، إذا كنت ترغب في الاستيلاء على العازلة الخاصة بهم (مع rdbuf) يمكنك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top