Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

28.07.2014, 09:58

Anwendung der Logfileklasse - Listing 8.15 unter Xcode

Hallo Zusammen,

ich habe nach dem Buch die Logfile Klasse programmiert, jedoch mit einigen kleinen Anpassungen. Da die Funktion zum
Das Programm lässt sich kompilieren und ausführen, doch schreibt er nur ein bisschen Datenschrott in die html-Datei. Bin gerade ein wenig mit meinem Latein am Ende.

Logfile.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef __LogImplementierung__Logfile__
#define __LogImplementierung__Logfile__

#include <iostream>
#include <fstream>
//#include <stdio.h>
//#include <windows.h>
#include "TSingleton.h"

// Defines
#define MAX_BUFFER  4096
#define L_FAIL      false
#define L_OK        true
#define g_pLogfile  Logfile::Get()

// Farben für Text
enum FONTCOLORS {
    BLACK,
    RED,
    GREEN,
    BLUE,
    PURPLE
};

class Logfile : public TSingleton<Logfile> {
    // Memberfkt
public:
    Logfile();
    ~Logfile();
    void createLogfile(const char *logName);
    void writeTopic(const char *topic, int size);
    void textout(const char *text);
    void textout(int color, const char *text);
    void textout(int color, bool list, const char *text);
    void ftextout(const char *text, ...);
    void ftextout(int color, const char *text, ...);
    void ftextout(int color, bool list, const char *text, ...);
    void functionResult(const char *name, bool result);
    
private:
    std::fstream m_Logfile;

};

#endif /* defined(__LogImplementierung__Logfile__) */


Logfile.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "Logfile.h"
#include <fstream>
using namespace std;

// constructor
// Aufgabe: bisher noch keine
Logfile::Logfile() {
    
}

// Destructor
// Gibt Meldung aus und schliesst das Logfile
Logfile::~Logfile() {
    textout("<p>End of logfile!</font></p></body></html>");
    textout("Destruktor!");
    m_Logfile.close();
}

// CreateLogfile
// Aufgabe Logfile erstellen und Kopf schreiben

void Logfile::createLogfile(const char *logName) {
    m_Logfile.open(logName, ios_base::in|ios_base::trunc);
    textout("Die ist ein Teststring, ob das schreiben wirklich funktioniert!");
    textout("<html><head><title>Logfile</title></head>");
    textout("<body><font face='courier new'>");
    writeTopic("Logfile", 3);
    
    // Aktuelle Build-Konfiguration ausgeben
    #ifdef _DEBUG
        textout("BUILD: DEBUG<br>");
    #else
        textout("BUILD: RELEASE<br>");
    #endif
    
    // Link für E-Mail Adresse schreiben
    textout("<a href='mailto:spam@internet>E-Mail</a>");
    
    // Logfile schiessen und mit append wieder öffnen
    m_Logfile.close();
    m_Logfile.open(logName, ios_base::out|ios_base::app);
}


// WriteTopic
// Aufgabe: Überschrifterzeugen

void Logfile::writeTopic(const char *topic, int size) {
    // Überschrift schreiben und flushen
    textout("<table cellspacing=0 cellpadding=0 width='100%%' bgcolor='#DFDFE5'");
    textout("\n<tr>\n<td>\n<font face='arial' ");
    ftextout("size='+%i'>\n", size);
    textout(topic);
    textout("</font>\n</td>\n</tr>\n</table>\n<br>");
    m_Logfile.flush();
}

// textout
// Aufgabe: Text ins Logfile schreiben (schwarz)

void Logfile::textout(const char *text) {
    // Text schreiben und flushen
    m_Logfile.write(text, sizeof(text));
    m_Logfile.flush();
} // textout (schwarze)

// textout
// Aufgabe: Text ins Logfile schreiben (farbig)

void Logfile::textout(int color, const char *text) {
    textout(color, false, text);
} // textout (farbig)

// textout
// Aufgabe: Text ins Logfile schreiben (farbig, liste)

void Logfile::textout(int color, bool list, const char *text) {
    // Listen schreiben
    if (list == true) {
        textout("<li>");
    }
    switch (color) {
        case BLACK:
            textout("<font color='black'"); break;
        case RED:
            textout("<font color='red'"); break;
        case GREEN:
            textout("<font color='green'"); break;
        case BLUE:
            textout("<font color='blue'"); break;
        case PURPLE:
            textout("<font color='purple'"); break;
    }
    
    // Text schreiben
    textout(text);
    textout("</font>");
    if (list == false) {
        textout("<br>");
    } else {
        textout("</li>");
    }
} // textout (farbig, liste)

void Logfile::ftextout(const char *text, ...) {
    char buffer[MAX_BUFFER];
    va_list pArgList;   // Liste übergebener Argumente
    va_start(pArgList, text);
    vsprintf(buffer, text, pArgList);
    va_end(pArgList);
    
    // Erzeugten String schreiben
    textout(buffer);
    
} // fTextout (schwarz)

// fTextout (farbe)
// Ausgabe: formatierten Text ins Logfile schreiben
void Logfile::ftextout(int color, const char *text, ...) {
    char buffer[MAX_BUFFER];
    va_list pArgList;   // Liste übergebener Argumente
    va_start(pArgList, text);
    vsprintf(buffer, text, pArgList);
    va_end(pArgList);
    
    // Erzeugten String schreiben
    textout(color, buffer);
    
} // fTextout (farbe)

// fTextout (farbe, liste)
// Ausgabe: formatierten Text ins Logfile schreiben
void Logfile::ftextout(int color, bool list, const char *text, ...) {
    char buffer[MAX_BUFFER];
    va_list pArgList;   // Liste übergebener Argumente
    va_start(pArgList, text);
    vsprintf(buffer, text, pArgList);
    va_end(pArgList);
    
    // Erzeugten String schreiben
    textout(color, list, buffer);
    
} // fTextout (farbe, liste)

// Function-Result
// Aufgabe: OK oder ERROR für Funktionsaufruf ausgeben

void Logfile::functionResult(const char *name, bool result) {
    if (L_OK == result) {
        textout("<table width='100%%' cellspacing='1' cellpadding='5'");
        textout(" border='0' bgcolor='#C0C0C0'><tr><td bgcolor=");
        ftextout("'#FFFFFF' width='35%'>%s</td>", name);
        textout("<td bgcolor='#FFFFFF' width='30%%'><font color=");
        textout("'green'>OK</FONT></TD><td bgcolor='#FFFFFF' ");
        textout("width='35%%'>-/-</TD></tr></table>");
    } else {
        textout("<table width='100%%' cellspacing='1' cellpadding='5'");
        textout(" border='0' bgcolor='#C0C0C0'><tr><td bgcolor=");
        ftextout("'#FFFFFF' width='35%'>%s</td>", name);
        textout("<td bgcolor='#FFFFFF' width='30%%'><font color=");
        textout("'red'>ERROR</FONT></TD><td bgcolor='#FFFFFF' ");
        textout("width='35%%'>-/-</TD></tr></table>");
        
    }
}


main.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include "TSingleton.h"
#include "Logfile.h"

using namespace std;

int main(int argc, const char * argv[])
{
    float kontrolle = 123.456f; // Variable zum Testen
    
    // Neues Logfile erstellen
    g_pLogfile->createLogfile("Logfile.html");

    // Überschrift erzeugen
    g_pLogfile->writeTopic("Unformatierter Text", 2);
    
    // unformatierten Text ausgeben
    g_pLogfile->textout("Normaler, schwarzer text<br>");
    g_pLogfile->textout(RED, "Farbiger Text");
    g_pLogfile->textout(BLUE, "Farbiger Text in Liste (1)");
    g_pLogfile->textout(BLUE, "Farbiger Text in Liste (2)");
    g_pLogfile->textout(BLUE, "Farbiger Text in Liste (3)");

    // Überschrift erzeugen
    g_pLogfile->writeTopic("Formatierter Text", 2);
    
    // Formatierten Text ausgeben
    g_pLogfile->ftextout("Kontrollvariable: %f<br>", kontrolle);
    g_pLogfile->ftextout(RED, "Kontrollvariable: %f", kontrolle);
    g_pLogfile->ftextout(GREEN, true, "Liste Kontrolle: %f", kontrolle);
    g_pLogfile->ftextout(GREEN, true, "Liste Kontrolle: %f", kontrolle*2.0f);
    g_pLogfile->ftextout(GREEN, true, "Liste Kontrolle: %f", kontrolle*4.0f);
    
    // eine erfolgreiche und eine fehlgeschlagene Funktion
    g_pLogfile->functionResult("Funktion 1", L_OK);
    g_pLogfile->functionResult("Funktion 2", L_FAIL);
    
    // Logfile schliessen
    g_pLogfile->Del();
    
    return 0;
}


die Klasse Singleton habe ich 1:1 aus dem Buch übernommen. Der Vollständigkeit halber, poste ich sie auch nochmal.
TSingleton.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#ifndef __Singleton__TSingleton__
#define __Singleton__TSingleton__

#include <iostream>

template <class T>
class TSingleton {
protected:
    static T *m_pSingleton; // Statisches Objekt

public:
    virtual ~TSingleton() {};
    
    // GET
    // Aufgabe: wenn nötig, statisches Objekt erzeugen und Zeiger darauf zurück geben.
    inline static T* Get() {
        if(!m_pSingleton)
            m_pSingleton = new T;
        
        return m_pSingleton;
    } // Get()
    
    // Statisches Objekt freigeben
    static void Del() {
        if (m_pSingleton) {
            delete (m_pSingleton);
            m_pSingleton = NULL;
        }
    } // Del()
};

// statische Variable erzeugen
template <class T>
T* TSingleton<T>::m_pSingleton = 0;

#endif /* defined(__Singleton__TSingleton__) */


So sieht das Ergebnis in der HTML Datei aus:

Quellcode

1
2
3
4
5
6
7
<table c
<tr>
<tsize='+2Unformat</font>
Normaler<font coFarbiger</font><br></l<font coFarbiger</font><br></l<font coFarbiger</font><br></l<font coFarbiger</font><br></l<table c
<tr>
<tsize='+2Formatie</font>
Kontroll<font coKontroll</font><br></l<li><fo<font coListe Ko</font></li><t<li><fo<font coListe Ko</font></li><t<li><fo<font coListe Ko</font></li><t<table w border='#FFFFFF<td bgco'green'>width='3<table w border='#FFFFFF<td bgco'red'>ERwidth='3<p>End oDestrukt

Es wirkt so, als wenn nur kleine Bruchstücke der Strings in die Datei geschrieben werden. Was übersehe ich?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

28.07.2014, 10:39

sizeof(text) ist Unfug. Da kommt 4 oder 8 raus, weil text ein Pointer ist.
Was Du da wohl willst, ist die Stringlänge zu ermitteln
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

28.07.2014, 10:46

:dash: haha

ja Du hast recht. hab es nun gegen strlen() ausgetauscht und das Ergebnis sieht aus, wie es soll. Besten Dank! :)

4

28.07.2014, 13:40

So, einige Anmerkungen:

Folgender Schnippsel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
void Logfile::createLogfile(const char *logName) {
    m_Logfile.open(logName, ios_base::in|ios_base::trunc);
    textout("Die ist ein Teststring, ob das schreiben wirklich funktioniert!");

    // ...
    
    // Logfile schiessen und mit append wieder öffnen
    m_Logfile.close();
    m_Logfile.open(logName, ios_base::out|ios_base::app);
}

1. Warum öffnen, schließen und erneut öffnen?
2. ios_base::in|ios_base::trunc: Das funktioniert?

Color ist ein enum (sinnvoller wäre hier ein strongly typed enum), warum übergibst du einen int?

Warum char* und keine std::strings?

Ist ein Singleton hier wirklich sinnvoll?

Der von dir erzeugt HTML-Output ist grauenvoll:
  • Fehlende Blockelemente
  • Listen gehören von ul/ol umschlossen
  • Font ist in HTML5 gestrichen
  • Für Überschriften gibt es entsprechende Elemente (<hx>), benutze keine Tabelle
  • <p>End of logfile!</font></p>
"Theory is when you know something, but it doesn’t work. Practice is when something works, but you don’t know why. Programmers combine theory and practice: Nothing works and they don’t know why." - Anon

Werbeanzeige