Seite 1 von 1
[gelöst] Stream out
Verfasst: 15. Oktober 2010 11:04
von soma
Hallo liebe Leute,
ich versuche mich seit dem Start meiner Projektarbeit in der GUI Programmierung mit Qt in C++.
Ich habe eine kleine Frage an euch, welche ihr wahrscheinlich mit links beantworten könnt.
Ich will eine Art logger implementiren, der mir bei jedem PushButten event, den gedrückten Button in eine datei schreibt.
Um alles so Modular wie möglich zu halten habe ich mir für den IOStream eine neue Klasse entworfen
Code: Alles auswählen
using namespace std;
IOclass::IOclass()
{
QFile file("log.csv");
if (!file.open (QIODevice::WriteOnly)) // Datei anlegen und auf Fehler prüfen
{
cout << "Datei konnte nicht angelegt werden: " << file.errorString ().toStdString () << endl;
}
QTextStream stream (&file);
}
void IOclass::WriteLog(char *text)
{
stream << text; // Text in die Datei schreiben
}
Aufrufen tu ich das ganze so:
Code: Alles auswählen
log = new IOclass;
...
log->WriteLog("ButtonName");
...
Hier wird mir aber gesagt: Device not Found.
Ich schätze, dass es hier an den Grundlagen von C++ Streams fehlt

Wird der Stream immer geschlossen, so dass er dem stream nichts mehr zuordnen kann? Wie kann ich den Stream offen lassen?
Um codeschnippsel wäre ich dankbar!
Und gibt es eine Funktion um an das Ende der geschriebenen Datei zu gelangen und dort einen neuen Text zu schreiben?
Vielen Dank!
Grüße Soma
Verfasst: 15. Oktober 2010 11:33
von Christian81
1. wie kann das überhaupt kompilieren?
2. Wie lange lebt 'stream' ?
Verfasst: 15. Oktober 2010 11:36
von soma
Erstmal danke für die Antwort.
Was ist denn falsch daran?
Ist ja nicht alles.
Und wie lange stream lebt würde ich ja auch gerne wissen?
Grüße Soma
Verfasst: 15. Oktober 2010 11:40
von Christian81
Stichwort: Lebenszeit von Variablen, hier besonders der von 'stream' im ctor.
Verfasst: 15. Oktober 2010 11:42
von pfid
soma hat geschrieben:Und wie lange stream lebt würde ich ja auch gerne wissen?
Hint: Bis zum Ende des Scopes

Verfasst: 15. Oktober 2010 11:51
von soma
OK hab ich verstanden.
Dumm von mir das so lösen zu wollen

Also muss ich die Datei immer direkt aufrufen, wenn ich was reinschreiben will.
Danke!
Aber wie gestallte ich jetzt den logger? Wie schreibe ich bei dem immer wieder geöffneten File an das Zeilenende?
Verfasst: 15. Oktober 2010 12:13
von RHBaum
Dein Problem ist weniger das streamen zu verstehen, als das Problem mit den Lebenszyklen von Instanzen.
1. Antwort:
dein STream sollte solange "leben" als wie du im Programm irgendwas loggen willst.
Theorethisch koenntest das IODevice und den stream jedesmal neu aufmachen, und neue texte anfuegen, wieder schliessen. aber das ist inperformant.
Besser, deinen stream komplett uber die laufzeit des progs laufen lassen.
es gibt noch zig andere Möglichkeiten.
Du koenntest auf die Errorconsole loggen (stderr)
du koenntest einen logdaemon zum loggen verwenden (unter linux gibts da einen, unter windows muesstest den EventLogger nehmen ... is aber IMHO overkill bei kleinen progs).
Dein hauptproblem ist also etwas zu erzeugen bevor, oder waehrend du das erste mal was loggen willst, und was erst am ende Deines progs freigegeben wird.
Da hasst grob 2 möglichkeiten:
1. du erzeugst das LogDingens, und gibst es allen die es brauchen im Constructor und / oder in den aufgerufenen funktionen als parameter mit.
2. wenn dir das aufblaehen der funktionen / Ctors zu unschoen ist, schau Dir das konzept eines Singletons an !
und 2.Antwort
Das du ne datei immer nur anhaengst, und nicht neu beschreibst, regelst du mit den "OpenModi" des files. Siehe Doku QFile !
Ciao ...
Verfasst: 15. Oktober 2010 18:49
von soma
Ok, 1000 Dank für deine Antwort. Dann stöber ich mal!
DANKE!
Verfasst: 16. Oktober 2010 12:37
von soma
Jetzt hab ich es:
Code: Alles auswählen
//Globale Definition von File:
QFile file("log.csv");
central::central(QWidget *parent) :
QWidget(parent)
{...
setStream();
...}
void setStream()
{
if (!file.open (QIODevice::WriteOnly)) // Datei anlegen und auf Fehler prüfen
{
std::cout << "Datei konnte nicht angelegt werden: " << file.errorString ().toStdString () << endl;
}
QTextStream stream(&file);
//Erste Zeile
stream << "Time" << " ; " << "Satus" << endl;
}
void central::logging(QString text, QFile & blar)
{
char time[10];
_strtime(time);
QTextStream stream(&blar);
stream << time << " ; " << text << endl;
}
//Aufruf logging:
logging("Textitext", file);
DANKE!
Verfasst: 16. Oktober 2010 18:27
von solarix
Es gibt immer viele Lösungen für ein Problem und nicht alle Lösungen müssen immer 100% perfekt sein, aber in diesem Fall sind unbedingt noch ein paar Kommentare notwendig:
Code: Alles auswählen
//Globale Definition von File:
QFile file("log.csv");
.... und
QTextStream stream(&blar);
stream << time << " ; " << text << endl;
}
Hast du die Anwendung von Membervariablen (privaten Variabeln in Klassen) begriffen? Beschäftige dich unbedingt nochmals mit dem Aufbau von sauberen Klassen..
Denke objektorientiert... eine Logklasse hat nichts mit der GUI zu tun! Log-Instanzen werden häufig nur einmal im Programm benötigt. Lies dazu mal was über Singleton-Klassen:
http://de.wikipedia.org/wiki/Singleton_ ... smuster%29 (/edit: wie von RHBaum bereits erwähnt aber von dir still ignoriert...)
Das löst dann auch das Problem mit globalen Variabeln...
Lern das von dir eingesetzte Werkzeug (Qt) unbedigt besser kennen und nutze es auch! Siehe
http://doc.trolltech.com/4.7/qdatetime. ... ntDateTime
hth...
Verfasst: 16. Oktober 2010 20:09
von soma
Meinst du bei dem ersten Kommentar, dass das Argument &blar gar nicht notwendig ist? ich hätte ihm ja auch gleich das file geben können?