fstream Problem
-
Hey cpp Community!

Ich habe ein kleines Problem in einer meiner Funktionen (bitte Styl nicht so sehr beachten, bin relativ neu in c++ :P).Ich möchte fehlgeschlagene Verbindungen in einer log.dat Datei loggen. Jedoch wird noch nicht mal eine log.dat Datei erstellt. Um nicht sofort zu euch zu rennen, habe ich es erstmal soweit wie möglich vereinfacht, um zu gucken, ob es vom Prinzip her gehen würde und das tat es. Daher bin ich im Moment ziemlich verzweifelt.
Testfunktion:
string ip = "HALLO LOG!"; time_t t; // Systemzeit time(&t); // für das Loggen fstream noHost; // Stream erstellen fstream noCon; // Stream erstellen noHost.open( "log.dat", ios::out | ios::app ); // Datei öffnen noHost << "- " << ctime(&t) << endl; noHost << "Host konnte nicht aufgeloest werden: "; noHost << ip << endl; noHost << endl; noHost.close(); // Datei schließen noCon.open( "log.dat", ios::out | ios::app ); // Datei öffnen noCon << "- " << ctime(&t) << endl; noCon << "Verbindung fehlgschlagen: "; noCon << ip << endl; noCon << endl; noCon.close(); // Datei schließenMeine Funktion:
int ping( string ip ) { // LOG int state = 0; // ---< WSADATA w; if( int result = WSAStartup(MAKEWORD(2,2), &w) != 0 ) { cout << "Winsock 2 Fehler #" << result << endl; return 1; } hostent* phe = gethostbyname(ip.c_str()); if( phe == NULL ) { cout << "\"" << ip << "\"" << " konnte nicht aufgeloest werden!\a\a" << endl; return 1; //LOG state = 1; } if( phe->h_addrtype != AF_INET ) { cout << "Ungueltiger Adresstyp!" << endl; return 1; } if(phe->h_length != 4) { cout << "Ungueltiger IP-Typ!" << endl; return 1; } int Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Verbindung herstellen if( Socket == -1 ) { cout << "Socket konnte nicht erstellt werden!" << endl; return 1; } sockaddr_in service; service.sin_family = AF_INET; service.sin_port = htons(80); // Das HTTP-Protokoll benutzt Port 80... char** p = phe->h_addr_list; // p mit erstem Listenelement initialisieren int result; // Ergebnis von connect do { if(*p == NULL) // Ende der Liste { cout << ip << ": "; cout << "Verbindung fehlgschlagen!\a\a" << endl; return 1; //LOG state = 2; } service.sin_addr.s_addr = *reinterpret_cast<unsigned long*>(*p); ++p; result = connect( Socket, reinterpret_cast<sockaddr*>(&service), sizeof(service) ); } while( result == -1 ); cout << ip << ": "; cout << "Verbindung erfolgreich!" << endl; // falls keine Verbindung time_t t; // Systemzeit time(&t); // für das Loggen fstream noHost; // Stream erstellen fstream noCon; // Stream erstellen switch( state ) { case 1: noHost.open( "log.dat", ios::out | ios::app ); // Datei öffnen noHost << "\n- " << ctime(&t) << endl; noHost << "Host konnte nicht aufgeloest werden: "; noHost << ip << endl; noHost << endl; break; case 2: noCon.open( "log.dat", ios::out | ios::app ); // Datei öffnen noCon << "\n- " << ctime(&t) << endl; noCon << "Verbindung fehlgschlagen: "; noCon << ip << endl; noCon << endl; break; } noHost.close(); // Datei schließen noCon.close(); // Datei schließen }Ich wusste nicht, ob die ganze Funktion relevant ist oder nur der letzte Teil, sorry wegen dem ganzen Code

-
Wozu für eine Log-Datei zwei open mit demselben Namen? Ein open reicht.
Benutze für diesen Zweck ofstrem statt fstream ohne weitere ios-Zusätze.ofstream log; // stream anlegen int Eintrag = 0; // testgrösse log.open("log.dat"); // datei öffnen log << "Eintrag: " << Eintrag << endl; // irgendetwas in die datei schreiben log.close(); // datei schliessen
-
hi berniebutt,
man kann aber auch einfach blind sein
Habe es umgehend umgeschrieben, sieht auch schon besser aus. Ich danke dir für deine Hilfe:), aber funktionieren will das Konstrukt trotzdem nicht.
state wird ganz am Anfang der Funktion deklariert und mit 0 initialisiert.
ofstream log; // stream anlegen log.open("log.dat"); // datei öffnen if( state == 1 ) { log << "\n- " << ctime(&t) << endl; log << "Host konnte nicht aufgeloest werden: "; log << ip << endl; log << endl; } else if( state == 2 ) { log << "\n- " << ctime(&t) << endl; log << "Verbindung fehlgschlagen: "; log << ip << endl; log << endl; } log.close(); // datei schliessenDas komische ist, dass es in einer seperate Datei super funktioniert und auch eine Datei erstellt wird. Jedoch in meiner Funktion will es einfach nicht funktionieren.
Bin ich einfach zu blöd oder einfach wieder nur zu blind.
-
Schau dir diese Zeilen noch mal genau an (bzw. die Warnungen deines Compilers!):
if(...) { return 1; //LOG state = 1; }
-
hi,
kann leider nicht wirklich nachvollziehen was du mir damit sagen willst. Wie gesagt, bin ziemlich neu in C++. Habe es schon mitstate = 1; return state;versucht, was aber ja gar nichts bringt, da ich die state var ja innerhalb der Funktion brauche und nicht als rückgabewert, oder?
Obwohl mir fällt da grad was ein. Ich werde mal versuchen das Logging in eine zweite Funktion zu schreiben, die mit dem übergebenen Parameter (Var) von Ping arbeitet. Ich melde mich, falls es nichts wird.

EDIT:
Es hat geklappt
Endlich kann losgeloggt werden.void logPing( string ip ) { int state = ping( ip ); // falls keine Verbindung time_t t; // Systemzeit time(&t); // für das Loggen ofstream log; // stream anlegen log.open("log.dat"); // datei öffnen if( state == 1 ) { log << "\n- " << ctime(&t) << endl; log << "Host konnte nicht aufgeloest werden: "; log << ip << endl; log << endl; } else if( state == 2 ) { log << "\n- " << ctime(&t) << endl; log << "Verbindung fehlgschlagen: "; log << ip << endl; log << endl; } log.close(); // datei schliessen }Ob das jetzt so schön gelöst ist, weiß ich natürlich nicht, aber immerhin funktioniert es nun. Danke dir für den Tipp Th69.
-
Hallo Croma,
jeder Anfang ist schwer - das ist normal. Probleme sind nun aber dafür da, gelöst zu werden. Dein Ansatz mit einer Log-Datei ist schon einmal sehr gut. Damit kann man viel machen, manchmal schneller und effizienter als mit Debuggen.
Erweitere die Ausgaben in die Log-Datei um die Kontrolle, was mit if ... else ... abgefragt wird - also hier deine Grösse state.
Ich mache seit 'Olims Zeiten' jede Programmentwicklung so und benutze debug nur selten. Hat den Vorteil, dass man vermeintlich fehlerfreie Dinge auskommentieren und jederzeit reaktivieren kann, wenn später doch etwas falsch läuft.
Th69 hat auch recht: Fehlermeldungen und Warnungen des Compilers sind auch zu beachten.
-
Hallo Chroma,
soweit solltest du die Grundlagen von C++ aber beherrschen, daß "return" deine Funktion beendet, d.h. die nachfolgenden Zeilen Code gar nicht mehr ausgeführt werden -> und daher auch kein Logging!
Aber deine 2. Variante mit der eigenen Log-Funktion ist auch besser - schön, daß du also selber etwas ausprobiert hast...
Du solltest dich auch mal mit dem Thema "Debugging" beschäftigen (je nachdem welche IDE bzw. Compiler du verwendest). Damit kannst du dann den Programmcode Zeile für Zeile abarbeiten (quasi "Loggen" ;)) ...
Sorry berniebutt, daß ich dir widerspreche, aber erst sollte man Debuggen lernen (wie man sieht, funktioniert sonst evtl. auch das Logging nicht richtig -)
-
Th69 schrieb:
Sorry berniebutt, daß ich dir widerspreche, aber erst sollte man Debuggen lernen (wie man sieht, funktioniert sonst evtl. auch das Logging nicht richtig -)
Das Loggen - wie es hier genannt wird - war ein allgemein übliches Verfahren zum Testen einer Programmentwicklung als es noch kein Debuggen gab. Bei einem sauberen Programmentwurf ist das sehr effektiv zur Vermeidung von Fehlern und zum Aufspüren, wo doch Fehler auftreten. Ich komme damit in den meisten Fällen schneller klar als mit Debug. Letztere Möglichkeit bleibt immer noch offen. Eine Datei öffnen und schliessen und zwischendurch hineinschreiben, was passiert, ist eine einfache Angelegenheit. Wenn dort etwas erwartetes nicht erscheint, so ist der Fehler leicht lokalisierbar.
Meine andere Meinung: Erst Loggen beherrschen und einsetzen, dann Debug verwenden! Ich denke sogar, das Loggen kann zu einem besseren Programmentwurf führen.
Hier sind wir aber beim Thema 'Programmierstil' und darüber kann man heftig diskutieren. Wichtig ist nur, dass ein Programmierer überall im Programm den Überblick behält, was während des Programmlaufes passiert oder eben nicht passiert. Diesen Überblick in eine Log-Datei zu integrieren ist auch sinnvoll für die spätere Wartung des Programmes. Warum crasht es auf einmal und wo genau? :p
edit: Die Log-Datei für den Benutzer sollte natürlich getrennt sein von der Log-Datei des Programmierers. Letztere kommentiert man aus oder löscht sie schlicht zum Ende der Release-Version