/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
wrapper til std::cout <<
Fra : Stephan Henningsen


Dato : 05-01-03 21:31

Hejsa.

Jeg sidder og skal til at udvikle et større projekt, og vil derfor
gerne starte med at lægge nogle kræfter i et test-miljø, som gør det så
nemt som muligt at afvikle nogle modultests.

I den anledning vil jeg gerne lave noget smart logging-funktionalitet,
som kræver mindst mulig indgreb i den egentlige, funktionelle kode i
projektet. Jeg har før prøvet mig lidt frem, men synes altid, jeg ender
med at give en std::string med som parameter, hvorfor alle ints, longs
mv. først skal konverteres.

Så nu vil jeg lave noget, der gør det muligt, at skrive sådan:

   debug << "x = " << x << ", " << 1.2 << '.';

I praksis en wrapper til std::cout, men hvor min egen kode "sluger"
stream'en, og evt. logger den i en fil og/eller fører den ud på
std::cout.

Indtil videre har jeg forsøgt at nedarve fra std::basic_streambuf<CharT>,
men er rendt ind i en intern compilerfejl i g++ 3.0, så jeg gi'r op her...

--
Stephan Henningsen

 
 
Helge Jensen (05-01-2003)
Kommentar
Fra : Helge Jensen


Dato : 05-01-03 23:10

Stephan Henningsen wrote:
> Hejsa.
>
> Jeg sidder og skal til at udvikle et større projekt, og vil derfor
> gerne starte med at lægge nogle kræfter i et test-miljø, som gør det så
> nemt som muligt at afvikle nogle modultests.

Hehe, jeg har lige lavet mig "ytest", der måske er noget for dig.

Kig på http://www.slog.dk/~jensen/software.html

Kast et blik på eksemplerne i http://www.slog.dk/~jensen/ytest/ytest.pdf

> I den anledning vil jeg gerne lave noget smart logging-funktionalitet,
> som kræver mindst mulig indgreb i den egentlige, funktionelle kode i
> projektet. Jeg har før prøvet mig lidt frem, men synes altid, jeg ender
> med at give en std::string med som parameter, hvorfor alle ints, longs
> mv. først skal konverteres.

Hvad med:

----- tostring.hpp -----
#include <sstream>

namespace util {
template <typename T>
const std::string tostring(const T& t) {
std::stringstream s;
s << t;
return s.str();
}
}
----- tostring.hpp -----

Det er da noget man altid kan bruge :)

> Så nu vil jeg lave noget, der gør det muligt, at skrive sådan:
>
>    debug << "x = " << x << ", " << 1.2 << '.';

Det bliver godt nok til:

#include "util/tostring.hpp"
using namespace util;
std::ostream& debug = std::cerr; // i en central .hpp og .cpp
debug << "x = " << tostring(x) << ", " << tostring(1.2) << '.';

> I praksis en wrapper til std::cout, men hvor min egen kode "sluger"
> stream'en, og evt. logger den i en fil og/eller fører den ud på
> std::cout.

Du kan vidst nøjes med at nedarve fra std::ostream, jeg prøver lige at
finde noget kode et sted...

--
Helge


Thomas Krog (06-01-2003)
Kommentar
Fra : Thomas Krog


Dato : 06-01-03 00:25

> Så nu vil jeg lave noget, der gør det muligt, at skrive sådan:
>
> debug << "x = " << x << ", " << 1.2 << '.';

hvad med:

#include <sstream>
std::stringstream debug;
debug << "x = " << x << ", " << 1.2 << '.';

derpå kan du gøre med debug hvad du vil fx. udskrive til cout med:
std::cout << debug.str();
og tilsidst tømme bufferen med
debug.str("");
så det gamle ikke kommer med i næste udskrift.



Stephan Henningsen (06-01-2003)
Kommentar
Fra : Stephan Henningsen


Dato : 06-01-03 20:53

On Mon, 06 Jan 2003 00:25:11 +0100, Thomas Krog wrote:

>> Så nu vil jeg lave noget, der gør det muligt, at skrive sådan:
>>
>> debug << "x = " << x << ", " << 1.2 << '.';
>
> hvad med:
>
> #include <sstream>
> std::stringstream debug;
> debug << "x = " << x << ", " << 1.2 << '.';
>
> derpå kan du gøre med debug hvad du vil fx. udskrive til cout med:
> std::cout << debug.str();
> og tilsidst tømme bufferen med
> debug.str("");
> så det gamle ikke kommer med i næste udskrift.

Det er ganske rigtigt noget i den dur, men jeg vil ikke til at kalde
debug.str("") og/eller ekstra filter- og logging-funktioner ved siden af;
jeg vil have det til at se mere transparrent i og med der streames til
debug. Om jeg må be' =)

--
Stephan Henningsen

Igor V. Rafienko (06-01-2003)
Kommentar
Fra : Igor V. Rafienko


Dato : 06-01-03 22:24

[ Stephan Henningsen ]

[ ... ]

> Det er ganske rigtigt noget i den dur, men jeg vil ikke til at kalde
> debug.str("") og/eller ekstra filter- og logging-funktioner ved
> siden af; jeg vil have det til at se mere transparrent i og med der
> streames til debug. Om jeg må be' =)


Hva er problemet, egentlig? Dersom du vil ha logging til _flere_
output kilder (slik fx. tee(1) gjør), kan du titte på hva Dietmar
Kuehl foreslo (fx. her: <URL:news:85baku$447$1@nnrp1.deja.com>).
Dersom du vil ha logging til _en_ output kilde, kan du grovt sett
gjøre det slik:


/* global static? */ std::ofstream ofs( "<wherever>" );

/* global */ std::ofstream &debug = ofs;

/* ... */

debug << <expression>;


Mao. 'debug' blir en referanse til en stream som er tilgjengelig ved
programmets oppstart[*] og som forblir åpen til programmet er
terminert.





ivr
[*] en hake: siden initialiseringsrekkefølgen på globale objekter (de
heter vel "objects with external linkage", om jeg ikke husker feil)
ikke er veldefinert (iallfall på tvers av "translation units"), så kan
det hende at du _ikke_ kan bruke 'debug' i akkurat slike objekter. Men
jeg har vansker med å se hvordan man skulle garantere at _ett_ bestemt
objekt blir skapt før _alle_ de andre, uten å fikle mye med det
konkrete runtime systemet.
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
            -- pederst på irc

Byrial Jensen (07-01-2003)
Kommentar
Fra : Byrial Jensen


Dato : 07-01-03 21:53

Igor V. Rafienko <igorr@ifi.uio.no> skrev:

> [*] en hake: siden initialiseringsrekkefølgen på globale objekter (de
> heter vel "objects with external linkage", om jeg ikke husker feil)
> ikke er veldefinert (iallfall på tvers av "translation units"), så kan
> det hende at du _ikke_ kan bruke 'debug' i akkurat slike objekter. Men
> jeg har vansker med å se hvordan man skulle garantere at _ett_ bestemt
> objekt blir skapt før _alle_ de andre, uten å fikle mye med det
> konkrete runtime systemet.

Det problem kan klares ved at lade en funktion returnere (en
reference til) et statisk objekt. Det vil så blive initialiseret
ved første brug kald af funktionen:

// Utestet kode
std::ofstream& debug()
{
static s("<wherever>");
return s;
}

main ()
{
debug() << "main started\n";
...
}

Helge Jensen (07-01-2003)
Kommentar
Fra : Helge Jensen


Dato : 07-01-03 01:10

Stephan Henningsen wrote:

> Det er ganske rigtigt noget i den dur, men jeg vil ikke til at kalde
> debug.str("") og/eller ekstra filter- og logging-funktioner ved siden af;
> jeg vil have det til at se mere transparrent i og med der streames til
> debug. Om jeg må be' =)

Jaja, du kræver nok!

Jeg har imidlertid fundet det kode jeg lovede. Ideen er, at man har en
implementation af std::ostream, der kun skriver noget hvis det man
"<<"'er har en tilstrækkelig "log-level".

f.eks:

#include "log_ostream.hpp"

logging::log_ostream debug(std::cerr, log_debug);
// stuff written here is debug, if you want it printed, you can:
debug << set_print(log_debug);

debug << "foo"
<< my_struct_that_has_operator<<(std::ostream&)
<< std::endl;

Implementationen er i log_stream.{hpp,cpp} (der er templates, da det
virker for std::basic_ostream<char_t, traits>).

Der er en test med i "logging_test.cpp", ret i logging_test.cpp's
include af log_stream.hpp hcis ikke du har logging_test.cpp liggende i
et subdir af "log_stream.hpp".

Læg mærke til den rare:

log_ostream os(any_ostream);
os << temp_level(log_trace) << "foo: " << "bar " << baz << std::endl;

Der logger med den level der er angivet til temp_level indtil et
sequence-point.


--
Helge



Helge Jensen (07-01-2003)
Kommentar
Fra : Helge Jensen


Dato : 07-01-03 11:04

Helge Jensen wrote:

How, det gamle kode havde vist et par små fejl. De er nu rettet, og
testen anerkender det .

--
Helge



Thomas Krog (07-01-2003)
Kommentar
Fra : Thomas Krog


Dato : 07-01-03 18:45

> Det er ganske rigtigt noget i den dur, men jeg vil ikke til at kalde
> debug.str("") og/eller ekstra filter- og logging-funktioner ved siden af;
> jeg vil have det til at se mere transparrent i og med der streames til
> debug. Om jeg må be' =)

hvad med nedenstående:

class Debug{
public:
template<typename T>
Debug& operator<<(const T& t){
// og her kan du vælge hvor debug skal hen fx:
std::cout << t;
return *this;
}
};

Debug hiddenDebug;
Debug& debug = hiddenDebug;



Søg
Reklame
Statistik
Spørgsmål : 177491
Tips : 31966
Nyheder : 719565
Indlæg : 6408458
Brugere : 218886

Månedens bedste
Årets bedste
Sidste års bedste