2008-10-28 36 views
8

में cout को प्रतिस्थापित करने के लिए एक स्ट्रिंगबफ को सही ढंग से लोड करने के लिए मैथवर्क्स वर्तमान में मैटब्लैब डेस्कटॉप खोलने पर मैटब्लॉक डेस्कटॉप को खोलने की अनुमति नहीं देता है क्योंकि उन्होंने stdout को रीडायरेक्ट किया है। उनका वर्तमान कामकाज एक समारोह प्रदान कर रहा है, mexPrintf, that they request you use instead। थोड़ा सा घूमने के बाद, मुझे लगता है कि मुझे जो चाहिए वह करने के लिए std :: stringbuf क्लास का विस्तार करना संभव है। यहां तक ​​कि मेरे पास अभी तक क्या है। क्या यह पर्याप्त मजबूत है, या क्या अन्य विधियों को अधिभारित करने या इसे करने का बेहतर तरीका है? (एक सामान्य यूनिक्स वातावरण में पोर्टेबिलिटी और अगर यह कोड एक MEX निष्पादन के खिलाफ जुड़ा हुआ नहीं है सामान्य रूप में std :: अदालत उपयोग करने की क्षमता के लिए खोज रहे)MATLAB MAX फ़ाइल

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());  

उत्तर

9

आप वास्तव में std :: stringbuf को अधिभारित नहीं करना चाहते हैं, तो आप std :: streambuf या std :: basic_streambuf (यदि आप एकाधिक वर्ण प्रकारों का समर्थन करना चाहते हैं) को अधिभारित करना चाहते हैं, तो आपको अतिप्रवाह विधि को ओवरराइड करने की आवश्यकता है कुंआ।

लेकिन मुझे यह भी लगता है कि आपको अपनी समस्या के समाधान पर पुनर्विचार करने की आवश्यकता है।

कोउट सिर्फ एक ओस्ट्रीम है, इसलिए यदि सभी वर्ग/कार्य एक ओस्ट्रीम लेते हैं तो आप अपनी पसंद की किसी भी चीज़ को पार कर सकते हैं। जैसे cout, ofstream, आदि

यदि यह बहुत कठिन है तो मैं अपना खुद का संस्करण बनाउंगा, जिसे शायद मायकआउट कहा जाता है जिसे या तो कंपाइलर समय या रनटाइम समय पर परिभाषित किया जा सकता है (आप जो करना चाहते हैं उसके आधार पर)।

एक सरल समाधान हो सकता है:

#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; 

और अदालत संस्करण बस हो सकता है:

typedef std::cout mycout; 

एक क्रम संस्करण में कुछ अधिक परिश्रम लेकिन आसानी से संभव है।

0

cout एक विशेष चरित्र उत्पादन धारा है। यदि आप cout चाहते हैं जो किसी फ़ाइल को लिखता है, तो fstream का उपयोग करें, खासकर ofstream। उनके पास एक ही इंटरफ़ेस है जो cout प्रदान करता है। इसके अतिरिक्त, यदि आप अपने बफर को पकड़ना चाहते हैं (rdbuf के साथ) आप कर सकते हैं।

9

शेन, आपकी मदद के लिए बहुत बहुत धन्यवाद। मेरा अंतिम कार्य कार्यान्वयन यहां है।

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); 
+0

एसडीडी स्ट्रीम बफर को बहाल करना बहुत महत्वपूर्ण साबित हुआ। ऐसा करने के बिना मेरे मैक्स फ़ंक्शन को कुछ प्रकार की मेमोरी समस्या और पुन: संकलित * पर क्रैश मैटलैब लग रहा था। –

1

मैं ओपी की अंतिम कार्यान्वयन एक छोटा सा बदल दिया है, एक जोड़ने निर्माता और विनाशक। इस वर्ग का ऑब्जेक्ट बनाना स्वचालित रूप से std::cout में स्ट्रीम बफर को प्रतिस्थापित करता है, और जब ऑब्जेक्ट स्कोप से बाहर हो जाता है, तो मूल स्ट्रीम बफर पुनर्स्थापित किया जाता है। आरए II!

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"; 

... और कुछ भी भूल के बारे में चिंता मत करो।