Kapitel 13

Alle Codedateien dieses Kapitels herunterladen

13_4_1_LoggerKlasse.cpp

Datei herunterladen

/*
 * Lösung für Übung 13.4.1 - Logger Klasse
 *
 * Als Ausgangspunkt wurde 11_5_2_SerialisierungAbstract.cpp gewählt
 * und die Logger-Klasse aus 13_2_Logdatei.cpp eingebaut
 */
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <json/json.h>

class Logger
{
public:
  Logger()
  {
    // Der zweite Parameter gibt an, dass an die Datei
    // angehängt werden soll (app steht für appending),
    // statt sie zu überschreiben
    outputFile = std::ofstream("log.txt",
      std::ios_base::app);
    writeTime(outputFile);
    outputFile << " --Logging gestartet--\n";

    // flush() stellt sicher, dass alles im Puffer fertig
    // in die Datei geschrieben wird, damit bei Abstürzen
    // nichts verloren geht.
    outputFile.flush();
  }
  void log(const std::string& line)
  {
    writeTime(outputFile);
    outputFile << " " << line << "\n";
    outputFile.flush();
  }
private:
  std::tm currentTime()
  {
  }
  void writeTime(std::ofstream& stream)
  {
    // Das aktuelle Datum abrufen
    std::time_t now = std::time(0);
    std::tm time;
    localtime_s(&time, &now);
    // Hinweis: Wenn Sie nicht unter Windows programmieren,
    // müssen Sie die obige Zeile austauschen mit:
    // localtime_r(&now, &time);
    stream << std::put_time(&time, "%Y-%m-%d %H:%M:%S");
  }
  std::ofstream outputFile;
};


struct SerializableType
{
  virtual std::string write() const = 0;
  virtual void read(const std::string& str) = 0;
};

struct Question : public SerializableType
{
  std::string question;
  std::string answer;
  int category = 0;
  void read(const std::string& str) override
  {
    // Deserialisierung: Auslesen aus einem String
    Json::Value jsonObj;
    Json::Reader().parse(str, jsonObj);
    // Abruf der gewünschten Eigenschaften
    question = jsonObj["question"].asString();
    answer = jsonObj["answer"].asString();
    category = jsonObj["category"].asInt();
  }
  std::string write() const override
  {
    // Serialisierung: Abspeichern in einem String
    Json::StreamWriterBuilder factory;
    Json::Value jsonObj;
    jsonObj["question"] = question;
    jsonObj["answer"] = answer;
    jsonObj["category"] = category;
    return Json::writeString(factory, jsonObj);
  }
};

struct User : public SerializableType
{
  std::string name;
  int id = 0;
  void read(const std::string& str)  override
  {
    Json::Value jsonObj;
    Json::Reader().parse(str, jsonObj);
    name = jsonObj["name"].asString();
    id = jsonObj["id"].asInt();
  }
  std::string write() const override
  {
    Json::StreamWriterBuilder factory;
    Json::Value jsonObj;
    jsonObj["name"] = name;
    jsonObj["id"] = id;
    return Json::writeString(factory, jsonObj);
  }
};

void printOnConsole(const SerializableType& type)
{
  std::cout << type.write() << std::endl;
}

int main()
{
  // Klasse zum Logging des Programmablaufs in einer Textdatei
  Logger logger;
  Question q1;
  q1.question = "Was macht es?";
  q1.answer = "Es leuchtet blau";
  q1.category = 2;

  // Erste Log-Ausgabe
  logger.log("Erstes Fragenobjekt erstellt");

  std::cout << q1.write() << std::endl;
  Question q2;
  q2.read(q1.write());

  // Zweite Log-Ausgabe
  logger.log("Zweites Fragenobjekt erstellt");

  std::cout << q2.write() << std::endl;

  User user;
  user.name = "Manfred";
  user.id = 17;
  logger.log("Nutzerobjekt erstellt");
  std::cout << user.write() << std::endl;

  printOnConsole(q1);
  printOnConsole(q2);
  printOnConsole(user);

  // Dritte Log-Ausgabe
  logger.log("Konsolenausgabe abgeschlossen");
  return 0;
}