|
| redirect af cout til buffer/array Fra : Henning S Larsen |
Dato : 05-07-02 11:10 |
|
Hej
Jeg har noget kode er skriver diverse debug info til cout.
Nu skal koden kører embedded, og jeg vil gerne have sendt det til en
"log-buffer" i stedet.
Hvordan gør jeg nemmest det?
mvh
Henning
| |
Thomas Krog (05-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 05-07-02 12:01 |
|
> Jeg har noget kode er skriver diverse debug info til cout.
> Nu skal koden kører embedded, og jeg vil gerne have sendt det til en
> "log-buffer" i stedet.
> Hvordan gør jeg nemmest det?
Hvis det er et stort program du ikke ønsker at ændre i kunne du gøre det
således:
#include <iostream>
#include < sstream>
namespace BufferCout{
std::stringstream cout;
}
int main(){
using BufferCout::cout;
cout << "to the buffer"; // her kunne hele dit nuværende program blive
kørt. Det er uændret og skriver til cout.
// nu kan du så bruge bufferen som du vil. Her udskriver jeg den til
skærmen:
std::cout << "the buffer contains" << endl;
std::cout << cout.str().c_str();
return 0;
}
| |
Thomas Krog (05-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 05-07-02 12:04 |
|
Lige et par rettelser:
> Jeg har noget kode er skriver diverse debug info til cout.
> Nu skal koden kører embedded, og jeg vil gerne have sendt det til en
> "log-buffer" i stedet.
> Hvordan gør jeg nemmest det?
Hvis det er et stort program du ikke ønsker at ændre i kunne du gøre det
således:
#include <iostream>
#include < sstream>
namespace BufferCout{
std::stringstream cout;
}
int main(){
using BufferCout::cout;
cout << "to the buffer"; // her kunne hele dit nuværende program blive
kørt. Det er uændret og skriver til cout.
// nu kan du så bruge bufferen som du vil. Her udskriver jeg den til
skærmen:
std::cout << "the buffer contains:\n";
std::cout << cout.str().c_str() << std::endl
return 0;
}
| |
Thomas Krog (05-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 05-07-02 12:16 |
|
Løsningen virker dog ikke hvis der står std::cout i programmet. Der findes
nok en mere robust metode at gøre det på. Det ville nok også være en fordel
at oprette sin egen stream i programmet:
class UserStream{};
UserStream userStream;
userStream<<"test";
Derved har man fuld kontrol over hvad der skal ske idet man kan overloade
template<class A>
UserStream& UserStream: erator<<(const A& a);
| |
Mogens Hansen (05-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 05-07-02 12:20 |
|
"Thomas Krog" <rick@kampsax.dtu.dk> wrote
[snip]
> Hvis det er et stort program du ikke ønsker at ændre i kunne du gøre det
> således:
>
> #include <iostream>
> #include < sstream>
>
> namespace BufferCout{
> std::stringstream cout;
> }
> int main(){
> using BufferCout::cout;
> cout << "to the buffer"; // her kunne hele dit nuværende program blive
> kørt. Det er uændret og skriver til cout.
>
> // nu kan du så bruge bufferen som du vil. Her udskriver jeg den til
> skærmen:
> std::cout << "the buffer contains" << endl;
> std::cout << cout.str().c_str();
> return 0;
> }
Det ligner et hack - der ikke engang virker.
Hvad sker der når en funktion i en anden fil skriver til cout ?
Venlig hilsen
Mogens Hansen
| |
Thomas Krog (05-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 05-07-02 12:23 |
|
> Det ligner et hack - der ikke engang virker.
jo jeg kan godt se din løsning er væsenligt mere robust.
> Hvad sker der når en funktion i en anden fil skriver til cout ?
kunne det ikke løses hvis alle inkluderer en header fil:
namespace BufferCout{
extern std::stringstream cout;
}
og BufferCout::cout kun er placeret i en cpp fil
| |
Mogens Hansen (05-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 05-07-02 12:17 |
|
"Henning S Larsen" <post.reply@to.group> wrote
[snip]
> Hvordan gør jeg nemmest det?
Du kan udskifte den streambuffer som cout bruger, med en type der er
passende til dit behov (tekst-buffer i memory, skriv til en fil, send til en
seriel port).
Se
Standard C++ IOStream and Locales
Angilika Langer and Klaus Kreft
ISBN 0-201-18395-1
side 72-76 for en detaljeret beskrivelse
#include <iostream>
#include <strstream>
template <typename StreamType>
class redirect_stream
{
public:
typedef std::basic_ios<
typename StreamType::char_type,
typename StreamType::traits_type> stream_basic_ios;
typedef std::basic_streambuf<
typename StreamType::char_type,
typename StreamType::traits_type> streambuf_type;
redirect_stream(StreamType& dest, StreamType& src) :
dest_(dest), strbuf_(0)
{
dest.exceptions(std::ios_base::goodbit);
dest.clear(src.rdstate());
strbuf_ = dest.stream_basic_ios::rdbuf(src.stream_basic_ios::rdbuf());
dest.copyfmt(src);
}
~redirect_stream()
{
dest_.stream_basic_ios::rdbuf(strbuf_);
}
private:
StreamType& dest_;
streambuf_type* strbuf_;
};
int main()
{
using namespace std;
cout << "This goes to standard \"cout\"" << endl;
{
char log_buffer[64*1024];
// ostrstream is depricated!!!
ostrstream log_stream(log_buffer, sizeof(log_buffer));
redirect_stream<ostream> redirect_cout(cout, log_stream);
cout << "This goes into \"log_streambuf\"" << ends;
cout.flush();
}
cout << "This goes to standard \"cout\"" << endl;
}
Venlig hilsen
Mogens Hansen
| |
|
|