2017-05-18 14 views
2

Ich schreibe ein Programm, das Schreiben des aktuellen Datums und der Uhrzeit in eine Protokolldatei erfordert, obwohl der Code funktioniert, gibt es eine Menge Code zu wiederholen. Der Code istWiederverwendung strftime in C++

#include<iostream> 
#include<fstream> 
#include<unistd.h> 

using namespace std; 

string logFile="/home/shared/c++/time.log"; 
char timeBuffer[80]; 

int main() 
{ 
    struct tm * timeInfo; 
    time_t rawtime; 

    ofstream vLog(logFile.c_str(), ios_base::app | ios_base::out); 
      { 
       { 
        time (&rawtime); 
        timeInfo = localtime(&rawtime); 
        strftime(timeBuffer,sizeof(timeBuffer),"%A %d %b %Y %r %Z",timeInfo); 
        string timeNow(timeBuffer); 
        cout << timeNow << " - Start of log." << endl; 
        vLog << timeNow << " - Start of log." << endl; 
       } 
       // Do a part of the code 
       { 
        time (&rawtime); 
        timeInfo = localtime(&rawtime); 
        strftime(timeBuffer,sizeof(timeBuffer),"%r",timeInfo); 
        string timeNow(timeBuffer); 
        cout << " " << timeNow << " - 1st Line of log." << endl; 
        vLog << " " << timeNow << " - 1st Line of log." << endl; 
       } 
       // Do more code 
       { 
        time (&rawtime); 
        timeInfo = localtime(&rawtime); 
        strftime(timeBuffer,sizeof(timeBuffer),"%r",timeInfo); 
        string timeNow(timeBuffer); 
        cout << " " << timeNow << " - 2nd Line of log." << endl; 
        vLog << " " << timeNow << " - 2nd Line of log." << endl; 
       } 
       // Do the last part of the code 
       { 
        time (&rawtime); 
        timeInfo = localtime(&rawtime); 
        strftime(timeBuffer,sizeof(timeBuffer),"%A %d %b %Y %r %Z",timeInfo); 
        string timeNow(timeBuffer); 
        cout << timeNow << " - End of log." << endl; 
        vLog << timeNow << " - End of log." << endl; 
       } 
     } 
} 

Ich habe zählen die {} auf jedem Abschnitt so, dass die Variablen nur für den einen bestimmten Codeblock verwendet werden. Wenn ich sie nicht benutze, bekomme ich Fehler beim Kompilieren.

time.cpp: In function "int main()": 
time.cpp:54:29: error: redeclaration of "std::string timeNow" 
    string timeNow(timeBuffer); 
          ^
time.cpp:45:11: error: "std::string timeNow" previously declared here 
    string timeNow(timeBuffer); 
     ^

Mit den geschweiften Klammern, dann kompiliert und läuft ohne Probleme.

Die Informationen, die in die Protokolldatei geschrieben werden, sind unterschiedlich und müssen daher von der Uhrzeit getrennt sein.

Da ich neu in C++ bin, habe ich das Gefühl, das Problem zu verkomplizieren, so dass jede Anleitung geschätzt würde. Ich bin mit CentOS 7 und g ++ (GCC) 4.8.5 20.150.623 (Red Hat 4.8.5-11)

Grüße Bernstein-Marie

aktualisieren

Vielen Dank für die Hilfe. Der vollständige Code lautet jetzt:

#include<iostream> 
#include<fstream> 
#include<unistd.h> 

std::string logFile="/home/shared/c++/time.log"; 
char timeBuffer[80]; 
void getTime(std::ofstream &vLog, const std::string &format_args, const std::string &message) 
{ 
    struct tm * timeInfo; 
    time_t rawtime; 
    time (&rawtime); 
    timeInfo = localtime(&rawtime); 
    strftime(timeBuffer,sizeof(timeBuffer),format_args.c_str(),timeInfo); 
    std::string timeNow(timeBuffer); 
    std::cout << timeNow << message << std::endl; 
    vLog<< timeNow << message << std::endl; 
} 

int main() 
{ 
    std::ofstream vLog(logFile.c_str(), std::ios_base::app | std::ios_base::out); 
    getTime(vLog, "%A %d %b %Y %r %Z", " - Start of logging"); 
    // Do part of the code 
    getTime(vLog, " %r", " - 1st line of log"); 
    // Do more code 
    getTime(vLog, " %r", " - 2nd line of log"); 
    // Do the last part of the code 
    getTime(vLog, "%A %d %b %Y %r %Z", " - End of logging"); 
    vLog << std::endl; 
    return (0); 
} 

Hoffentlich werden andere dies hilfreich finden.

Bernstein-Marie

Antwort

1

eine Funktion Schreiben Sie Ihren Code zu wickeln. Die Parameter sollten ofstream, strftime Format Argument und die Log-Meldung ("- 1. Zeile Code", ..) sein

void foo(ofstream &vLog, const string &format_args, const string &message) 
{ 
    struct tm * timeInfo; 
    time_t rawtime; 

    time (&rawtime); 
    timeInfo = localtime(&rawtime); 
    strftime(timeBuffer,sizeof(timeBuffer),format_args.c_str(),timeInfo); 
    string timeNow(timeBuffer); 
    cout << timeNow << message << endl; 
    vLog<< timeNow << message << endl; 
} 

int main() 
{ 
    ofstream vLog(logFile.c_str(), ios_base::app | ios_base::out); 

    foo(vLog, "%A %d %b %Y %r %Z", " - 1st Line of log."); 
    // Do a part of the code 
    foo(/* second call */); 
    // Other stuff 
    foo(/* 3rd call */); 
    // ... 

    return 0; 
} 
+0

Vielen Dank dafür, es hat den Code viel einfacher zu lesen und sehr flexibel aufgrund des Sendens der strftime Variablen und der Protokollnachricht gemacht –

0

Das Problem ist, dass Sie die Variable „TimeNow“ sind erneut deklariert werden und ruft den Konstruktor es den Wert von „timeBuffer“ zu geben. Dies funktioniert mit Klammern, da jede Klammer ein neuer Bereich ist. Jede Deklaration von "timeNow" ist für alle anderen Deklarationen davon unsichtbar, so dass es beim Compiler keine Verwirrung gibt. Um dies zu umgehen, verwenden Sie Zuweisung, anstatt zu versuchen, die Variable neu zu deklarieren. Verwenden Sie timeNow = timeBuffer

statt

string timeNow(timeBuffer); 

ich diesen Code ausprobiert und es funktioniert g ++ verwenden auf meinem Ende:

int main() 
    { 
     struct tm * timeInfo; 
     time_t rawtime; 

     ofstream vLog(logFile.c_str(), ios_base::app | ios_base::out); 


         time (&rawtime); 
         timeInfo = localtime(&rawtime); 
         strftime(timeBuffer,sizeof(timeBuffer),"%A %d %b %Y %r %Z",timeInfo); 
         string timeNow(timeBuffer); 
         cout << timeNow << " - Start of log." << endl; 
         vLog << timeNow << " - Start of log." << endl; 

        // Do a part of the code 

         time (&rawtime); 
         timeInfo = localtime(&rawtime); 
         strftime(timeBuffer,sizeof(timeBuffer),"%r",timeInfo); 
         timeNow = timeBuffer; 
         cout << " " << timeNow << " - 1st Line of log." << endl; 
         vLog << " " << timeNow << " - 1st Line of log." << endl; 

        // Do more code 

         time (&rawtime); 
         timeInfo = localtime(&rawtime); 
         strftime(timeBuffer,sizeof(timeBuffer),"%r",timeInfo); 
         timeNow = timeBuffer; 
         cout << " " << timeNow << " - 2nd Line of log." << endl; 
         vLog << " " << timeNow << " - 2nd Line of log." << endl; 

        // Do the last part of the code 

         time (&rawtime); 
         timeInfo = localtime(&rawtime); 
         strftime(timeBuffer,sizeof(timeBuffer),"%A %d %b %Y %r %Z",timeInfo); 
         timeNow = timeBuffer; 
         cout << timeNow << " - End of log." << endl; 
         vLog << timeNow << " - End of log." << endl; 
} 
+0

Ich habe den Code nach Ihrem Vorschlag geändert und es funktioniert auch für mich, so dass eine gute Besserung. Gibt es eine Möglichkeit, den Timecode je nach Format einmal oder zweimal zu verwenden und dann in das Protokoll zu schreiben? –

0

Ja, das ist möglich :)

Lassen Sie uns zunächst Faktor aus der ganzen getting- und-Formatieren-der-Zeit-Geschäft. Die einzige Variable, was in der duplizierten Code ist der Format-String, also lassen Sie uns einen Parameter machen:

std::string formattedCurrentTime(char const *const format) { 
    std::time_t const rawTime = std::time(nullptr); 
    std::tm const *const timeInfo = std::localtime(&rawTime); 

    char buffer[80]; 
    std::size_t const length = std::strftime(buffer, sizeof buffer, format, timeInfo); 

    return {buffer, buffer + length}; 
} 

Dann können wir bei der Vervielfältigung der Logging-Linien aussehen.Eine allgemeine Lösung ist ein bisschen schwierig, weil die ganzen operator << Überlastung und Polymorphismus Unternehmen zu implementieren, aber Ihr Fall sieht genug konsequent aus einer maßgeschneiderten Lösung profitieren:

auto const logBookend = [&](std::string const &message) { 
    auto const timeNow = formattedCurrentTime("%A %d %b %Y %r %Z"); 

    std::cout << timeNow << " - " << message << std::endl; 
    vLog  << timeNow << " - " << message << std::endl; 
}; 

auto const logLine = [&](std::string const &message) { 
    auto const timeNow = formattedCurrentTime("%r"); 

    std::cout << timeNow << " - " << message << std::endl; 
    vLog  << timeNow << " - " << message << std::endl; 
}; 

Hinweis: siehe this question warum nicht zu Verwenden Sie using namespace std;.

See it live on Coliru!