Forum: PC-Programmierung C++ cout umleiten


von Bernd (Gast)


Lesenswert?

Hi,

folgendes Problem: Ich habe eine Klasse von streambuf abgeleitet, um 
cout (umzubiegen). Sehe nachfolgenden Code.
1
class NRedirectStream : public streambuf {
2
  HWND  control;
3
public:
4
  //typedef std::char_traits<char> traits_type; 
5
  //typedef traits_type::int_type  int_type; 
6
7
  NRedirectStream(HWND hwnd) {
8
    control = hwnd;
9
  };
10
  virtual streamsize xsputn(const char_type *_Ptr,  streamsize _Count) {
11
    unsigned long length = GetWindowTextLength(control);
12
    wchar_t *text = new wchar_t[length+_Count*2+1];
13
    GetWindowText(control, text, length+1);
14
    wchar_t* target = text+length;
15
    const char* source = _Ptr;
16
    for (int i = 0; i<_Count; i++) {
17
      char c = *source++;
18
      if (c == '\n') *target++ = '\r';
19
      *target++ = (wchar_t)c;
20
    }
21
    *target = 0;
22
    SetWindowText(control, text);
23
    delete [] text;
24
    return _Count;
25
    return __super::xsputn(_Ptr, _Count);
26
  };
27
28
    virtual int_type overflow(int_type c) { 
29
      return traits_type::not_eof(c);
30
    };
31
};

Das ganze funktionniert auch teilweise.
Beispiel:

cout << "Der Name ist " << name << ".\n";

Von dieser Zeile wird für "Der Name ist " und ".\n" jeweils xsputn 
aufgerufen. Nur für die Variable name (vom Type string in C++) nicht.
Weiß jemand, woran es liegen kann, dass Literale richtig verarbeitet 
werden und Strings (c++ Klasse string) als Variable keinen Aufruf von 
xsputn erzeugen? Auch wenn ich int, long, float übergebe, streikt meine 
Klasse.

von Jorge (Gast)


Lesenswert?

name ist nicht const

von Hermann-Josef (Gast)


Lesenswert?

Hallo Bernd,

hier könnte sich ggf. ein Hinweis dazu finden:
  http://www.inf.uni-konstanz.de/~kuehl/c++/iostream/
siehe das Beispiel wstream.cc.

Leider funktionieren die Beispiele dort evtl. nicht mehr mit einem 
neueren Kompiler (gcc 3.3.x oder 4.x). Eines (prfxstream.cc) habe ich 
mal umgestrickt.

Die Idee ist eigentlich, dass die neue Stream-Klasse von std::ostream 
ableitet, damit hat die neue Klasse automatisch alle <<-Operatoren 
mitgeerbt.

Dann implementiert man eine streambuf-Klasse, die mit dem eigentlichen 
Problem zu tun hat, und die man im Konstruktor der neuen Klasse dem 
Konstruktor von std::ostream als Argument übergibt.

Was sich in der C++-Implementierung gegenüber (vermutlich) gcc 2.95 
geändert hat, sind die Namen der Methoden zum Synchronisieren der 
streambufs, falls man die benötigt.

Etwas komplexerer Code findet sich meines Wissens auch bei Boost, hier 
in einer beim letzten Besuch der Web-Site nicht akzeptierten 
Implementierung einer Logging-Klasse.

Viel Erfolg
Hermann-Josef

von Hermann-Josef (Gast)


Lesenswert?

... hmmh, das löst das Problem wohl nicht wirklich, es sei man ersetzt 
im gesamten Code cout durch den eigenen ostream.

Wie wäre es den streambuf in cout durch einen eigenen zu ersetzen?

http://bytes.com/forum/thread133345.html

Hermann-Josef

von Arc N. (arc)


Lesenswert?


von Bernd (Gast)


Lesenswert?

Ich habe es jetzt geschaft das Beispiel hier 
(http://www.codeproject.com/KB/edit/editlog.aspx) erfolgreich zu 
übertragen.

Aber eigentlich ist es immer noch nicht das Gelbe vom Ei.

Um in die Standardausgabe zu schreiben gibt es unter C++/CLI folgende 
Möglichkeiten:

1. printf(...)               // C Variante
2. cout << ...               // C++ Variante
3. Console::WriteLine(...)   // C++/CLI Variante

Bisher funktioniert keine der Varianten für alle drei Formen.

Eigenlich wird immer nur auf Klassenebene (Beispiel 2 und 3) gearbeitet.
Wie aber bekomme ich den WAHREN Datenstrom, den Windows tatsächlich an 
ein Konsolenfenster schickt? Denn die Varianten 1-3 senden ja alle auch 
gemischt in einer Anwendung Text an das gleiche Konsolenfenster. 
Irgendwo müssen die Datenströme ja zusammenlaufen.

von Jorge (Gast)


Lesenswert?

Unter Unix heissen die 1 2 und 3 "stdin" "stdout" "stderr" ich glaub bei 
Windoof ist es das gleiche

von Jorge (Gast)


Lesenswert?


von I_ H. (i_h)


Lesenswert?

Mal eine Frage: Wieso willst du cout eigentlich umleiten? Die Shell kann 
das in den meisten Fällen viel besser.

von Bernd (Gast)


Lesenswert?

> Mal eine Frage: Wieso willst du cout eigentlich umleiten? Die Shell kann
> das in den meisten Fällen viel besser.

Weil ich ein paar C++ Klassen habe, die z.B. cout verwenden. C++/CLI 
Klassen verwenden Console::Write und alte C funktionen printf. Und ich 
möchte diese Ausgaben in ein .NET TextBox beziehungsweise in ein Windows 
Edit Control umleiten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.