problem Systemzeit + Countdowns
-
Hallo.
In meinem Programmier Leistungskurs habe ich eine Echtzeit-Systemzeit-Ausgabe programmiert, die dann zusätzlich noch Countdowns drunterhängen hat (Pausenzeiten der Schule).
Meine Fragen:
-Wie mache ich das, dass die angezeigten Countdowns verschwinden, sobald sie ablaufen bzW. garnicht erst auftauchen, sofern die Zeilzeit des Countdowns schon abgelaufen ist?
-Wie kann ich, anders als bisher in meinem Programm, die Countdowns bestimmen, indem ich sie vorher eingebe?? (Habe ja jetz im Quelltext schon alle 3 Countdowns definiert, bzW. die Zielzeit dieser Countdowns)
-Wie krieg ich es hin, die Countdowns so aussehen zu lassen:
Noch 2 Std:31 Min:21 Sek bis zur ersten Pause
Noch 3 Std:31 Min:21 Sek bis zur zweiten Pause(ACHTUNG: Sind jetzt nicht die original Zeiten :))
Bitte um Vorschläge
MfG, Axel
-
Zeig mal ein wenig mehr Code, wie du die Countdowns erzeugst, zwischenspeicherst und ausgibst.
-
also das mit dem verschwinden könnte man so lösen:
if(/*countdown 1 abgelaufen*/) { system("cls");//löscht die komplette ausgabe der konsole }
und die anderen countdowns werden ja eh immer aktualisiert, somit bleibt die konsole nicht länger als 1sec leer.
das mit dem ausgabeformat könnte man z.B. so lösen:
cout<<"bitte geben Sie ein in wie vielen minuten die Pause ist!\n"; int minuten_gesamt; cin>>minuten_gesamt; int stunden=minuten_gesamt/60; int minuten=minuten_gesamt-(stunden*60); cout<<"noch "<<stunden<<":"<<minuten<<" bis zur Pause!\n";
falls du die minuten nicht eingeben möchtest musst du einfach eine feste uhrzeit definieren wann die pause ist und dich an der systemzeit orientieren.
das mit dem aktualisieren lässt sich so lösen:( am besten mit multithreading)
#include<windows.h> #include<windowsx.h> #include<stdio.h> #include<conio.h> using namespace std; int timer1_stunden; int timer2_stunden; int timer3_stunden; int timer1_minuten; int timer2_minuten; int timer3_minuten; int timer1_sekunden; int timer2_sekunden; int timer3_sekunden; DWORD WINAPI aktualieren_thread(LPVOID IpParameter) { } DWORD WINAPI Timer1(LPVOID IpParameter1) { } DWORD WINAPI Timer2(LPVOID IpParameter2) { } DWORD WINAPI Timer3(LPVOID IpParameter3) { } int main() { DWORD processID; HANDLE aktualisieren_thread_handle=CreateThread(0, 0, aktualisieren_thread, 0, 0, processID); DWORD processID1; HANDLE timer1_handle=CreateThread(0, 0, Timer1, 0, 0, processID1); DWORD processID2; HANDLE timer2_handle=CreateThread(0, 0, Timer2, 0, 0, processID2); DWORD processID3; HANDLE timer3_handle=CreateThread(0, 0, Timer3, 0, 0, processID3); WaitForSingleObject(aktualisieren_thread, INFINITE); WaitForSingleObject(Timer1, INFINITE); WaitForSingleObject(Timer1, INFINITE); WaitForSingleObject(Timer1, INFINITE);
aber etwas code wäre in der tat gut
mfg,
andi01.
-
Hier mein Quelltext:
//--------------------------------------------------------------------------- #pragma hdrstop #include <iostream> #include <ctime> #include <stdlib> #include <stdio.h> #include <conio.h> using namespace std; //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { int ZeitBuffer[4][3]; ZeitBuffer[0][0] = 9; ZeitBuffer[0][1] = 05; ZeitBuffer[0][2] = 00; ZeitBuffer[1][0] = 10; ZeitBuffer[1][1] = 55; ZeitBuffer[1][2] = 00; ZeitBuffer[2][0] = 12; ZeitBuffer[2][1] = 40; ZeitBuffer[2][2] = 00; ZeitBuffer[3][0] = 14; ZeitBuffer[3][1] = 30; ZeitBuffer[3][2] = 00; time_t Zeitstempel; tm *nun; int altezeit; //[schleifen anfang hier] while (!kbhit()) { Zeitstempel = time(0) ; nun = localtime(&Zeitstempel); if (nun->tm_sec != altezeit) { clrscr(); cout << nun->tm_mday << '.' << nun->tm_mon+1 << '.' << nun->tm_year+1900 << " - " << nun->tm_hour << ':' << nun->tm_min << ':' << nun->tm_sec << endl; if ((ZeitBuffer[0][0]-nun->tm_hour > 0) || (ZeitBuffer[0][1]-nun->tm_min > 0) || (ZeitBuffer[0][2]-nun->tm_sec > 0)) cout << "/tErste Pause: noch " << ZeitBuffer[0][0]-nun->tm_hour << ":" << ZeitBuffer[0][1]-nun->tm_min << ":" << ZeitBuffer[0][2]-nun->tm_sec; else if ((ZeitBuffer[1][0]-nun->tm_hour > 0) || (ZeitBuffer[1][1]-nun->tm_min > 0) || (ZeitBuffer[1][2]-nun->tm_sec > 0)) cout << "/tZweite Pause: noch " << ZeitBuffer[1][0]-nun->tm_hour << ":" << ZeitBuffer[1][1]-nun->tm_min << ":" << ZeitBuffer[1][2]-nun->tm_sec; else if ((ZeitBuffer[2][0]-nun->tm_hour > 0) || (ZeitBuffer[2][1]-nun->tm_min > 0) || (ZeitBuffer[2][2]-nun->tm_sec > 0)) cout << "/tDritte Pause: noch " << ZeitBuffer[2][0]-nun->tm_hour << ":" << ZeitBuffer[2][1]-nun->tm_min << ":" << ZeitBuffer[2][2]-nun->tm_sec; else if ((ZeitBuffer[3][0]-nun->tm_hour > 0) || (ZeitBuffer[3][1]-nun->tm_min > 0) || (ZeitBuffer[3][2]-nun->tm_sec > 0)) cout << "/tSchulschluss: noch " << ZeitBuffer[3][0]-nun->tm_hour << ":" << ZeitBuffer[3][1]-nun->tm_min << ":" << ZeitBuffer[3][2]-nun->tm_sec; else cout << "/tSchule is aus..."; altezeit = nun->tm_sec; } } //[schleifen ende hier] getch(); return 0; } //---------------------------------------------------------------------------
-
am besten orientierst du dich dabei an der systemzeit, das ist die einfacjste methode. un um alle timer immer aktuell zu halten und in main währenddessen was anderes tun zu lönnen nimmst du am besten mukltithreading(siehe oben!).
was das mit dem verschwinden betrifft einfach ne funktion in aktualisieren einbauen:
if(stunden_timer1==0&&minuten_timer1==0&&sekunden_timer1==0) { Closehandle(timer1); system("cls"); }
mfg,
andi01.
-
Danke schonmal, ich werde mich morgen damit befassen und wenn ich weiter bin stell ich das fertige programm nochmal rein hier.
Danke, mfG, Axel
-
AxelH1992 schrieb:
Hier mein Quelltext:
int ZeitBuffer[4][3];
@AxelH1992
Ohne die Diskussion von gestern wieder aufwärmen zu wollen. Aber an der Stelle
des Codes musste ich einfach lachen. Weist du wie man dieses "Konstrukt" was du
da hast nennt?!Zu deiner 2. Frage. Dazu musst du die Zeiten in das obige "Konstrukt" eingeben,
jedoch bist du dann auf maximal 4 Countdowns begrenzt. Am einfachsten würde
es funktionieren wenn du anstatt diesem "Konstrukt" einen std::vector nimmst.
Dieser "Datentyp" wird automatisch größer wenn du mehr Werte einlesen willst.
Google einfach mal danach und lese dich ein wenig darin ein. Das wird dich
dann schnell weiterbringen denke ich.~Um diesen Post zu verstehen muss man die bisherigen Posts des OP kennen.~
-
lol
-
Weist du wie man dieses "Konstrukt" was du
da hast nennt?!Hmmm...
This ... is the Construct.
It's our loading program.
We can load anything, from clothing ... to equipment ... weapons ... training simulations ... anything we need.~Musste da nur gerade dran denken, weil man ein solches "Konstrukt" ja auch manchmal als~ Matrix bezeichnet.
-
Threads sind schon eine verdammt kreative Lösung...
-
-
lol
-
Shick ich später zu www.thedailywtf.com
-
ach menno, jz habt ihr ihn ganz verjagt
-
So Axel hier ist jetzt mal eine Version die auch funktioniert, allerdings ist nur unter Linux getestet, sollte aber ohne große Probs. auf dem C++ Builder von Borland laufen, dafür einfach das #define CBUILDER auskommentieren.
Wenn eine(r) den C++ Builder hat kann er das ja mal auf seinem System testen. Ich gehe jetzt ins Bett, gute Nacht...
// nächste Zeile auskommentieren wenn auf Borland C++ kompilliert wird // #define CBUILDER #ifdef CBUILDER #pragma hdrstop #endif #include <iostream> #include <sstream> #include <iomanip> #include <ctime> #include <cstdlib> #include <stdio.h> #ifdef CBUILDER #include <conio.h> #endif using namespace std; //--------------------------------------------------------------------------- /** Konstantendefinitionen besser an den Anfang **/ // enthält die Pausenzeiten const int ZeitBuffer[ ][3] = {{ 9,05,00}, {10,55,00}, {12,40,00}, {14,30,00}}; // std::vector<string> auch möglich - string aber nicht dynamisch const string Zustand [ ] = { "Erste Pause: " , "Zweite Pause: ", "Dritte Pause: ", "Schulschluss: " }; /** @name AktuellesDatum * @return string : aktuelles Datum und Zeit im Format * DD.MM.YYYY - HH:NN:SS * @param tm* timeinfo : aktuelle lokale Zeit **/ string AktuellesDatum(tm* timeinfo) { ostringstream out; // Anpassen der Zeichenbreite und festlegen Füllzeichen // setw und setfill out << setw(2) << setfill('0') << timeinfo->tm_mday << '.' << setw(2) << setfill('0') << timeinfo->tm_mon+1 << '.' << timeinfo->tm_year + 1900 << " - " << setw(2) << setfill('0') << timeinfo->tm_hour << ':' << setw(2) << setfill('0') << timeinfo->tm_min << ':' << setw(2) << setfill('0') << timeinfo->tm_sec; return out.str(); } /** IstAktuellePause() * Prüft ob die aktuelle Zeit noch vor der Pausenzeit liegt * @return bool : Diese Pause ist die aktuelle nächste Pause * @param const int* : Array von Pausenzeit-Daten * @param tm* timeinfo : aktuelle lokale Zeit **/ bool IstAktuellePause(const int Buffer[], tm* timeinfo) { return ( ( Buffer[0] * 3600 + Buffer[1] * 60 + Buffer[2]) > ( timeinfo->tm_hour * 3600 + timeinfo->tm_min * 60 + timeinfo->tm_sec ) ); } /** Restzeit() * @return string : Die Zeit bis zur nächsten Pause von 00:00:00 Uhr an, * berechnet aus Pausenzeit-Daten * @param const int* : Array von Pausenzeit-Daten * @param tm* timeinfo : aktuelle lokale Zeit **/ string Restzeit(const int Buffer[], tm* timeinfo) { ostringstream out; int min, sec; // lässt sich noch optimieren... z.B mit Abfrage auf negative Werte min = ( (Buffer[1] > timeinfo->tm_min) ? (Buffer[1] - timeinfo->tm_min) : (Buffer[1] - timeinfo->tm_min + 60 ) ); sec = ( (Buffer[2] > timeinfo->tm_sec) ? (Buffer[2] - timeinfo->tm_sec) : (Buffer[2] - timeinfo->tm_sec + 60 ) ); // Anpassen der Zeichenbreite und festlegen Füllzeichen // setw und setfill out << setw(2) << setfill('0') << ( Buffer[0] - timeinfo->tm_hour ) << ":" << setw(2) << setfill('0') << ( min ) << ":" << setw(2) << setfill('0') << ( sec ); return out.str(); } /** ZeitBisPause() * @return string : Die Zeit bis zur nächsten Pause * @param tm* timeinfo : aktuelle lokale Zeit **/ string ZeitBisZurPause(tm* timeinfo) { ostringstream out; for (int i = 0; i < 4; i++) if (IstAktuellePause(ZeitBuffer[i], timeinfo)) { out << Zustand[i] << " noch " << Restzeit(ZeitBuffer[i], timeinfo); return out.str(); } out << "Schule is aus..."; return out.str(); } #ifdef CBUILDER #pragma argsused #endif int main(int argc, char* argv[]) { time_t rawtime; tm *timeinfo; int oldtime; /** schleifen anfang hier **/ #ifdef CBUILDER // windows variante while (!kbhit()) #else // linux variante while(1) #endif { rawtime = time(0) ; timeinfo = localtime(&rawtime); // gibt einen Pointer auf eine statische // Struktur zurück NICHT freigeben! // Aktualisierung im Sekundentakt if (timeinfo->tm_sec != oldtime) { #ifdef CBUILDER clrscr(); // c builder // system("clr"); // in windows würde diese variante auch gehen cout << "Abbruch mit bel. Taste" << endl; #else system("clear"); // posix variante cout << "Abbruch mit [CTRL-C]" << endl; #endif cout << AktuellesDatum (timeinfo) << endl; cout << ZeitBisZurPause(timeinfo) << endl; // Sekunde für den nächsten Zeitvergleich speichern oldtime = timeinfo->tm_sec; } } /** schleifen ende hier **/ #ifdef CBUILDER getch(); // Fenster offenhalten - DEBUG #endif return 0; }
-
Also meinen Quelltext habt ihr ja schon gesehen. Der basiert natürlich darauf, dass der Benutzer nicht erst noch die Anzahl der Countdowns und die Endzeit der Countdowns eingibt, sondern schon 4 Countdowns existieren.
Funktioniert auch soweit, nur habe ich in der Rechnung (denke ich) noch irgendwo Probleme, denn ich bekomme ja die Systemzeit in Echtzeit ausgegeben, und darunter dann je einen Countdown.
So, jetzt kann ich ja anhand meiner Endzeit dieses Countdowns (die ich ja weiss) und anhand der Echtzeit-Ausgabe der Systemzeit ausrechnen, was dann beim Countdown stehen müsste.Aber da habe ich folgendes Probelm:
Bei den Sekunden des Countdowns habe ich permanent einen Minuswert, und der ist identisch mit dem Sekundenwert der Systemzeit. (Systemzeit= 50 / Countdown= -50)
bei den Minuten gibt es so ziemlich das selbe Problem:
Ihr seht ja in meinem Quelltext, der erste Countdown hat die Endzeit 9:05:00
Jetzt ist folgendes in der Ausgabe der Fall:
Systemzeit= 4:8:40 / Countdown= 5:-3:-408-3=5, das sind die 5 Minuten aus der Endzeit des Countdowns, aber warum erscheint das in der Ausgabe hinterher dann so seltsam??
Sofern ich dieses Problem (hoffentlich mit eurer Hilfe) beheben konnte,
würde ich ganz gern folgende modifizierungen einbauen:-Keine vorbestimmten Countdowns, sondern der Benutzer soll erst bestimmen wie viele Countdowns es geben soll, und definiert diese dann danach (gibt dessen Endzeiten in Std/Min/Sek ein), ODER
-Der Benutzer wird ein Mal aufgefordert einen Countdown in Std/Min/Sek zu definieren und wird dann (mit einer Schleife) gefragt, ob er einen weiteren einfügen möchte.Was bei mir funktioniert:
-Die Systemzeit wird tadellos in Echtzeit ausgegeben
-Die Countdowns werden nicht ALLE 4 angezeigt, sondern immer nur der, der als nächstes abläuft
-Wenn ein Countdown abläuft, verschwindet dieser und der nächste tritt an die Stelle des vorherigen CountdownsIch könnte mir zu meinen geplanten Modifizierungen schon was vorstellen, von dem ich mir erhoffe dass es funktioniert, aber das probiere ich erstmal aus bevor ich es einbaue.
Ich bitte um Lösungsvorschläge zu meinem Problem mit der Ausgabe, und Vorschläge für den Einbau meiner geplanten Modifikation.
Bitte versucht so wenig wie möglich Neues einzubringen, versucht den vorhandenen Quelltext zu "verändern" (wenn möglich), ok?
Danke im Vorraus, und wie immer mfG, Axel
Edit: hier nochmal der Quelltext
//--------------------------------------------------------------------------- #pragma hdrstop #include <iostream> #include <ctime> #include <time.h> #include <stdlib> #include <stdio.h> #include <conio.h> using namespace std; //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { int ZeitBuffer[4][3]; ZeitBuffer[0][0] = 9; ZeitBuffer[0][1] = 05; ZeitBuffer[0][2] = 00; ZeitBuffer[1][0] = 10; ZeitBuffer[1][1] = 55; ZeitBuffer[1][2] = 00; ZeitBuffer[2][0] = 12; ZeitBuffer[2][1] = 40; ZeitBuffer[2][2] = 00; ZeitBuffer[3][0] = 14; ZeitBuffer[3][1] = 30; ZeitBuffer[3][2] = 00; time_t Zeitstempel; tm *nun; int altezeit; while (!kbhit()) { Zeitstempel = time(0) ; nun = localtime(&Zeitstempel); if (nun->tm_sec != altezeit) { clrscr(); cout<<nun->tm_mday<<'.'<<nun->tm_mon+1<<'.'<<nun->tm_year+1900<<" - "<<nun->tm_hour<<':'<<nun->tm_min<<':'<<nun->tm_sec<<endl; if ((ZeitBuffer[0][0]-nun->tm_hour > 0) || (ZeitBuffer[0][1]-nun->tm_min > 0) || (ZeitBuffer[0][2]-nun->tm_sec > 0)) cout << "Erste Pause: noch " << ZeitBuffer[0][0]-nun->tm_hour << ":" << ZeitBuffer[0][1]-nun->tm_min << ":" << ZeitBuffer[0][2]-nun->tm_sec; else if ((ZeitBuffer[1][0]-nun->tm_hour > 0) || (ZeitBuffer[1][1]-nun->tm_min > 0) || (ZeitBuffer[1][2]-nun->tm_sec > 0)) cout << "Zweite Pause: noch " << ZeitBuffer[1][0]-nun->tm_hour << ":" << ZeitBuffer[1][1]-nun->tm_min << ":" << ZeitBuffer[1][2]-nun->tm_sec; else if ((ZeitBuffer[2][0]-nun->tm_hour > 0) || (ZeitBuffer[2][1]-nun->tm_min > 0) || (ZeitBuffer[2][2]-nun->tm_sec > 0)) cout << "Dritte Pause: noch " << ZeitBuffer[2][0]-nun->tm_hour << ":" << ZeitBuffer[2][1]-nun->tm_min << ":" << ZeitBuffer[2][2]-nun->tm_sec; else if ((ZeitBuffer[3][0]-nun->tm_hour > 0) || (ZeitBuffer[3][1]-nun->tm_min > 0) || (ZeitBuffer[3][2]-nun->tm_sec > 0)) cout << "Schulschluss: noch " << ZeitBuffer[3][0]-nun->tm_hour << ":" << ZeitBuffer[3][1]-nun->tm_min << ":" << ZeitBuffer[3][2]-nun->tm_sec; else cout << "Schule is aus..."; altezeit = nun->tm_sec; } } getch(); return 0; } //---------------------------------------------------------------------------
-
Danke, DeepCopy, ich werde das mal ausprobieren.
Und, auch wenn es ein wenig beschämend für mich ist, dass du meine Aussage über int und float in deine Signatur gepackt hast, auch danke dafür. ^^
Naja ich bleibe dennoch dabei, unser Proggen lehrer hat es uns so vermittelt, ich wende das dann auch so an, es sei denn, jemand belehrt mich mit einem praktischen Beispiel eines Besseren(Soll jetzt keine Anregung sein, mir praktische Beispiele zu vermitteln ;))
Danke nochmal, mfG, Axel
Edit:
DANKE DEEPCOPY
Dein Quelltext hat mich grad sozusagen erleuchtet !!!
Ich habe ihn sogar verstandenVielen Dank, du bist ein Meister!
*Huldigt ihm*
So ich muss um 5 raus also werde ich noch ein wenig "Ant Me!" lesen und dann zur Schule pilgern
Euch Allen ne gute Nacht und erholsame C++ TräumeMfG, Axel
-
Du hast cout.flush(); direkt nach cout<<endl; nur einmal aufgerufen. Man muß cout.flush(); aber nach cout<<endl; dreimal aufrufen, um notwendige Interferenzen zu vermeiden.
-
volkard schrieb:
Du hast cout.flush(); direkt nach cout<<endl; nur einmal aufgerufen. Man muß cout.flush(); aber nach cout<<endl; dreimal aufrufen, um notwendige Interferenzen zu vermeiden.
Kannst du mir dafür ein Beispiel nennen? Ich hatte es in der Vorlesung so verstanden, wenn cout.flush() aufgerufen wird ist der Buffer garantiert leer.
EDIT: Im obigen Code geändert!
AxelH1992 schrieb:
Dein Quelltext hat mich grad sozusagen erleuchtet !!!
Ich habe ihn sogar verstandenDas freut mich, achte mal die Unterschiede in der Funktion zur Berechnung wann die nächste Pause anfängt, die funktioniert in deiner Version überhaupt nicht richtig, verändere mal "On The Fly - während das Programmläuft" das Systemdatum von z.B. 23:50 auf 00:50, dann siehst du was ich meine, was dein Programm anzeigt hängt vom Zufall der gewählten Pausenzeit ab.
AxelH1992 schrieb:
-Wenn ein Countdown abläuft, verschwindet dieser und der nächste tritt an die Stelle des vorherigen Countdowns
Nein leider nicht, warum siehe weiter oben, achte in deiner Version auch mal auf die Berechnung der Restzeit und verändere mal "On The Fly" die Systemzeit dabei, du wirst feststellen das diese nur dann Negativ für Minuten und Sekunden ist wenn die aktuelle Zeit für Minuten und Sekunden größer ist als die Pausenzeit für Minuten und Sekunden.
AxelH1992 schrieb:
Vielen Dank, du bist ein Meister!
Danke, das gebe ich gleich mal weiter an: volkard, Nexus, camper, unskilled, SP, .... und alle die ich vergessen habe...
nein wirklich das sind DIE Grundlagen von denen ich gesprochen habe, ein paar Schleifen, in bisschen cin und cout, einfache Datentypen, Arrays, ein paar Funktionsaufrufe fertig. Keine Klassen, keine Vererbung, keine Konstruktoren, keine überladnenen Operatoren, kein STL, kein TR1, keine Pointer-Arithmetik, keine Allokation ... usw. usw. usw...Mach mal weiter du bist auf dem "Richtigen Weg"
-
DeepCopy schrieb:
volkard schrieb:
Du hast cout.flush(); direkt nach cout<<endl; nur einmal aufgerufen. Man muß cout.flush(); aber nach cout<<endl; dreimal aufrufen, um notwendige Interferenzen zu vermeiden.
Kannst du mir dafür ein Beispiel nennen? Ich hatte es in der Vorlesung so verstanden, wenn cout.flush() aufgerufen wird ist der Buffer garantiert leer.
Den Teil hast Du richtig verstanden. Nur bei endl fehlt was ganz entscheidendes. Eigentlich wollte ich sagen, daß man nach endl nicht EINMAL flushen soll, wie Du es dort getan und für das einzig Wahre dargestellt hast.
cout << ZeitBisZurPause(timeinfo) << endl; /** Wichtig! **/ cout.flush(); // Den output-Buffer vollständig leeren // (alles auf die Konsole schreiben)
Mit http://www.cplusplus.com/reference/iostream/manipulators/endl/ kommst Du bestimmt in Sekunden drauf, warum ich dort lachen mußte.
~Nimm int oder float. Aber aufpassen, immer nur einen dieser Datentypen pro Programm benutzen, sonst vertut sich der Compiler ganz gerne mal.~