vorgehensweise eigene Funktionen schreiben
-
Visual Studio2008
Win32 - XP ProfessionalHallo zusammen,
ich möchte "## ",Datum," -", Uhrzeit und Username sowie " > " für eine Dateiausgabe in ein ostream 'schreiben':
sollte dann so aussehen: "## 16.07.2010 - 13:45 Meyer > .."Dazu benötige ich die 'localtime_s' aus 'time.h' und die Funktion 'GetUserName'
Ferner vermutlich die Formatier-Funktion 'fprint_s' für zweistellige(Monat) bzw vierstellige(Jahr) Formatierung.Wie muss ich vorgehen, wenn ich eine Funktion schreiben will, welche mir die Daten für den 'ostream' aufbereitet.
lt. MSDN
errno_t _localtime_s( struct tm* _tm, const time_t *time ); //z.B. tm* aktuelleZeitHier erhalte ich wohl über aktuelleZeit-> die einzelnen Werte.
//z.B. Formatiert "16.07.2010" char datum[11]; sprintf_s(datum,sizeof(datum), "%02d.%02d.%04d", aktuelleZeit->tm_mday,...Das gleiche für die Uhrzeit:
// z.B. Formatiert "13:45" char uhrzeit[6] sprintf_s(uhrzeit,sizeof(uhrzeit), "%02d:%02d",aktuelleZeit->tm_hour,aktuelleZeit->tm_min);Welchen Rückgabewert muss die Funktion bekommen, damit die Ausgabe mit
//beispielsweise std::ostream ausgabe; ausgabe << Funktionsname.Rückgabewert ?? << "weiterer Text" ;eingegeben werden kann?
Ich hatte schon char versucht, konnte jedoch die beiden Pointer Datum und Uhrzeit nicht 'verknüpfen'. Ich habe auch strncat_s versucht - Nur habe ich mittlerweile so viel experimentiert dass ich überhaupt nicht(s) mehr weiß.
Einiges ließ sich sogar Fehlerfrei kompilieren - stürzte jedoch hinterher gnadenlos ab.Wie sollte die Funktion aussehen ?
Wie geht man am besten vor? oder ist der Ansatz schon verkehrt?Vielen Dank für Hinweise
ein ständiger Anfänger
-
Deine Funktion sollte eine Zeichenkette zurückgeben, dies wird mittels std::string oder char* repräsentiert. Tu dir selbst einen Gefallen und nimm std::string, wenn du komplizierte Zeichenkettenoperationen machst. Alternativ kann ich dir auch einen std::stringstream empfehlen, das müsste auch ganz gut zu dem passen, was du da vor hast (wobei ich nicht genau verstanden habe, was du überhaupt willst).
Außerdem noch zwei Bemerkungen:
1. In der ctime (so heißt nun die time.h) findest du auch eine Funktion um eine Zeit in eine Zeichenkette umzuwandeln strftime oder so ähnlich heißt die.
2. Mix nicht so wild C und C++. Manchmal bietet die C Bibliothek zwar gute Lösungen, aber gerade bei Zeichenketten macht man es sich oftmals sehr viel schwerer als es mit std::string wäre.
-
Vielen Dank für die Info.
Das ich c und c++ so wild durcheinander habe, war mir gar nicht bewusst. Danke.
Es ging mir nur darum ein bisschen zu testen, wie ich eigene Funktionen mit Rückgabewert schreibe. Hier wollte ich beispielsweise Datum und Zeit usw. in einen vorformatierten 'Text' bringen und diesen Rückgabewert in eine Datei schreiben.
Ich werde es mit 'strftime' noch einmal versuchen.
Gruß aus Bremen
-
eine ganz einfache logging-klasse könnte so aussehen:
#include <ctime> #include <sstream> #include <stdexcept> template<typename LOGGING_STREAM> struct basic_logger_t { basic_logger_t(LOGGING_STREAM& stream, const std::string& /*date_format*/ = "NOT USED", const std::string& /*time_format*/ = "NOT USED") : stream(stream) { stream << "started at " << get_date() << ", " << get_time() << std::endl; } template<typename T> LOGGING_STREAM& operator<< (const T& to_logg) { stream << get_time() << '\t'; return stream << to_logg; } private: std::string get_date() const { std::tm localtime = get_localtime(); std::stringstream ss; _add(ss, localtime.tm_mday); ss << '.'; _add(ss, localtime.tm_mon+1); ss << '.'; ss << localtime.tm_year+1900; return ss.str(); } std::string get_time() const { std::tm localtime = get_localtime(); std::stringstream ss; _add(ss, localtime.tm_hour); ss << ':'; _add(ss, localtime.tm_min); ss << ':'; _add(ss, localtime.tm_sec); return ss.str(); } #if defined(_MSC_VER) static std::tm _get_localtime(const std::time_t& to_convert) {// msvc provide a safer funtion for getting localtime std::tm ret_val; errno_t failed = localtime_s(&ret_val, &to_convert); if(failed != 0) throw std::runtime_error("failed to find out localtime"); return ret_val; } #else static std::tm _get_localtime(const std::time_t& to_convert) { std::tm ret_val; ret_val = *std::localtime(&to_convert); return ret_val; } #endif static std::tm get_localtime() { std::time_t time = std::time(0); return _get_localtime(time); } template<typename INTEGER> static void _add(std::stringstream& ss, INTEGER to_add) { if(to_add < 10) ss << '0'; ss << to_add; } LOGGING_STREAM& stream; private: /*forbidden*/ basic_logger_t(); basic_logger_t(const basic_logger_t& /*other*/); basic_logger_t& operator= (const basic_logger_t& /*other*/); }; typedef basic_logger_t<std::ostream> logger_t;genutzt wird das ganze dann so:
int main() { std::ofstream logging_file("log.txt"); logging_file.exceptions( std::ifstream::eofbit | std::ifstream::failbit | std::ifstream::badbit ); logger_t logger(logging_file); logger << "programm gestartet" << std::endl; }wie man sieht, könnte man mit dem time-format noch was anstellen, aber da hatte ich dann keine lust mehr(war ne hausarbeit und nicht alles nötig^^)

die komische einrückung resultiert aus 2 namespace-ebenen, aber da hatte ich keine lust, das alles anders einzurücken^^die exceptions für den stream zu aktivieren, erschien mir einfacher, als jedesmal die failbits nachzugucken ;o)
und bei einer ausgabe, sollte ja nun nicht wirklich was schief gehen - ich wüsste zumindest nicht, was passieren sollte, was keine exception "wert" wäre.bb
-