Uhrzeit/Datum-Addition
-
Hallo,
Ich habe ein Problem mit meinem ersten "richtigen" C++ Programm. Und wie man schon an meinem ersten Satz erkennen kann, bin ich absolute Neuling in diesem BereichZu meinem Problem:
Ein Freund von mir wollte einen Datum/Uhrzeitrechner. Da er noch weniger Kenntnisse im Bereich programmieren hat, hab ich mich entschlossen das mal anzugehen um auch ein wenig vom Lerneffekt bei der Sache zu profitieren. Ich bin mir ziemlich sicher das es viele viel einfachere Wege gibt um zum gewünschten Ergebnis zu kommen, aber auf Grund meiner geringen Kenntnisse habe ich den einzigen, mir bekannten Weg gewählt und das ganze wahrscheinlich ziemlich umständlich gemacht. Nachdem ich also die eingegebenen Tages-, Monats-, Jahres-, Stunden und Minutenwerte addiert habe, komme ich bei höheren Zahlen zu einem Ergebnis von bspw.: 21:65 Uhr. Um das zu verhindern, habe ich einen if-Befehl eingebaut, der überprüft ob zB die Minutenanzahl >= 60 ist und falls das der Fall ist, beim Stundenwert 1 addiert und anschließend beim Minutenwert 60 subtrahiert, um wieder auf die richtige Zeit zu kommen. Mit den Tagen und Stunden hab ich es ähnlich gelöst (if stundenwert >= 20, Tageswert +1 und Stundenwert -24). Soweit klappt das auch ganz ordentlich, bis auf den Stundenwert. Sobald der Minutenwert 60 überschreitet, wird zwar 60 subtrahiert, aber beim Stundenwert nicht 1 addiert. Komischerweise klappt dies mit den Tages- und Stundenwerten, bei denen ich exakt das gleiche Verfahren benutze.Hier einfach mal der Code:
int main() { int tag; int monat; int jahr; int stunde; int minute; cout<<"Bitte Tag eingeben\n"; cin>>tag; cout<<"Bitte Monat eingeben\n"; cin>>monat; cout<<"Bitte Jahr eingeben\n"; cin>>jahr; system("cls"); cout<<"Bitte Stunde eingeben\n"; cin>>stunde; cout<<"Bitte Minute eingeben\n"; cin>>minute; system ("cls"); int wtag; int wstunde; int wminute; cout<<"Bitte Tage eingeben\n"; cin>>wtag; cout<<"Bitte Stunden eingeben\n"; cin>>wstunde; cout<<"Bitte Minuten eingeben\n"; cin>>wminute; system ("cls"); int ztag = (tag+wtag); int zstunde = (stunde+wstunde); int zminute = (minute+wminute); if (zminute>=60) { zstunde = (stunde+wstunde+1); zminute = (minute+wminute-60); } if (zstunde>=24) { zstunde = (stunde+wstunde-24); ztag = (tag+wtag+1); } cout<<"Enddatum: "<<ztag<<"."<<monat<<"."<<jahr<< " , "<<zstunde<<":"<<zminute<<"Uhr\n"; system("PAUSE"); }
Kann mir jemand sagen wo der Fehler liegt bzw. was ich falsch gemacht habe? Außerdem würde ich mich auch über weitere Lösungsmöglichkeiten für diese Addition freuen, weil ich schließlich etwas lernen möchte
Danke schon mal im voraus
mfG idk
-
diese additionen/subtraktionen verstehe ich nicht so ganz ein einfachs
+
reicht
if (zminute >= 60) { //zstunde = zstunde + 1; //zstunde += 1; zstunde++; // <- c++ version, die oberen sind identisch zminute -= 60; } if (zstunde >= 24) { zstunde -= 24; ztag++; }
-
Naja, also das es so enfach ist habe ich nicht gedacht und ich bin auch nicht draufgekommen einfach ++ einzusetzen. Aber - ich bin wirklich erstaunt- es funktioniert tatsächlich, obwohl ich so wenig verändert habe
Vielen vielen Dank für die schnelle Hilfe
Echt Super!Eine Frage hätte ich allerdings noch:
Wie bekomme ich es hin, dass der Minutenanzahl eine 0 angefügt wird? Wenn zB die Minutenanzahl unter 10 liegt, wird zB: 21:5 ausgegeben, wobei es korrekt 21:05 sein müsste. Wie bekomme ich nun die 0 vor die minutenanzahl?vielen dank
mfG idk
-
Dies erreichst du über die IO-Manipulators, kleines Beispiel:
#include <iomanip> #include <iostream> int main() { std::cout << std::setfill('0') << std::setw(2) << 0; std::cout << ':'; std::cout << std::setfill('0') << std::setw(2) << 0; std::cout << ':'; std::cout << std::setfill('0') << std::setw(2) << 0; // Statt system("PAUSE"), die bessere Alternative: std::cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); std::cin.get(); return 0; }
Referenz: http://www.cplusplus.com/reference/iostream/manipulators/
Wenn ich dir zudem noch ein paar Tipps geben darf:
1. Verzichte aufsystem
. Wie man das automatische schliessen verhindert, erfährst du hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-111042.html
Wiesosystem
schlecht ist, steht hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-39453.htmlZudem sei noch gesagt, dass eigentlich ein automatisches schliessen verhindern eher ungewöhnlich ist. Ein Konsolenprogramm startet man schliesslich normalerweise aus der Konsole und wenn dort sich das Programm beendet, dann bleibt die Konsole offen
Desweiteren verzichte dringends auf diesystem("cls")
. Ich würde jeden Programmierer köpfen, welcher es wagt meine Konsole komplett zu leeren ohne nachzufragen
2. Setze nur Klammern, wenn sie benötigt werden oder wenn sie etwas hervorheben sollen. Die Klammern in zum Beispiel so einem Ausdruck sind völlig unnötig:zminute = (minute+wminute-60); // Ist das gleiche: zminute = minute + wminute - 60; // Beachte auch, durch das Einfügen von ein paar Abständen, ist des deutlich lesbarer.
3. Rücke einheitlich ein.
Grüssli
-
Hey,
vielen Dank für die Tipps...echt hilfreich.zu den Tipps:
1. system ("Pause"); hab ich nur benutzt, da das meine erste Lösung zu dem Problem war. Hab aber dank deines Links verstanden warum ich das besser sein lasse
2. system ("cls") werde ich nun auch versuchen auszulassen. Wie du bereits erwähnt hast, könnte das ärgerliche Folge für den Anwender habe, an die ich vorher nicht gedacht habe.
3.Werde mich von nun an bemühen sowohl Klammern auszulassen, als auch ordentlich einzurückenVielen Dank.
Weiß vllt. jemand eine Lösung für das Problem meines 2. Posts?
"Eine Frage hätte ich allerdings noch:
Wie bekomme ich es hin, dass der Minutenanzahl eine 0 angefügt wird? Wenn zB die Minutenanzahl unter 10 liegt, wird zB: 21:5 ausgegeben, wobei es korrekt 21:05 sein müsste. Wie bekomme ich nun die 0 vor die minutenanzahl? "Wäre echt stark wenn ich das auch noch in den Griff bekäme
mfG idk
-
idontknow schrieb:
"Eine Frage hätte ich allerdings noch:
Wie bekomme ich es hin, dass der Minutenanzahl eine 0 angefügt wird? Wenn zB die Minutenanzahl unter 10 liegt, wird zB: 21:5 ausgegeben, wobei es korrekt 21:05 sein müsste. Wie bekomme ich nun die 0 vor die minutenanzahl? "Das hat Dravere schon beantwortet (tip: das setw(2) ist dafür verantwortlich bei der Ausgabe).
-
idontknow schrieb:
Weiß vllt. jemand eine Lösung für das Problem meines 2. Posts?
Dravere hatte da eigentlich schon eine Lösung gepostet:
Dravere schrieb:
Dies erreichst du über die IO-Manipulators, kleines Beispiel:
#include <iomanip> #include <iostream> int main() { std::cout << std::setfill('0') << std::setw(2) << 0; std::cout << ':'; std::cout << std::setfill('0') << std::setw(2) << 0; std::cout << ':'; std::cout << std::setfill('0') << std::setw(2) << 0; // Statt system("PAUSE"), die bessere Alternative: std::cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); std::cin.get(); return 0; }
Referenz: http://www.cplusplus.com/reference/iostream/manipulators/
Edit: Argh, zu langsam...
-
Achsoo..
LoL. Ich dachte das wäre einfach nur i-ein Code um mir das:
std::cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); std::cin.get();
zu zeigen
Aber okay, dann werd ich mal schauen was sich damit machen lässt.
Vielen Dank an alle Poster
Echt super! Schnelle Hilfe, gut erklärt und freundlich....
bin höchst zufrieden mit den bisherigen Ergebnissen
mfG idk
-
Mhm. Scheint irgendwie nicht zu funktioniere. Muss ich an Draveres Code noch irgendwas ändern? Hab den einfach unter if (Minutenanzahl<10) eingefügt. Wenn ich nun das Programm laufen lasse, erscheint immer noch XX:5 statt XX:05. Hab schon versucht einzelne Sachen einzusetzen, aber hat auch nie zum erfolg geführt.
Kann mir jemand sagen, was ich falsch mache?
if (zminute<10) { std::cout << std::setfill('0') << std::setw(2) << 0; std::cout << ':'; std::cout << std::setfill('0') << std::setw(2) << 0; std::cout << ':'; std::cout << std::setfill('0') << std::setw(2) << 0; }
Also zminute ist die Variable für die Minutenanzahl. Wollts nur nochma erwähnen
mfG idk
-
Ja kann ich. Du bist auf meine Falle getreten. Dieser Code ist nicht Copy&Paste fähig, sondern zeigt nur auf, wie es geht. Damit soll verhindert werden, dass Programmierer Lösungen einfach nur in ihren Code kopieren und nicht verstehen, was sie eigentlich tun. Wenn man meinen Code verstanden hat, kann man ihn ohne Probleme auf deinen Code anwenden, da sind nur leichte Umformungen nötig.
Ich empfehle dir zum Beispiel mal die Referenz zu lesen, welche ich angegeben habe. Vor allem könntest du dort den Haupttext lesen und dann die Texte zu
setw
undsetfill
.
Danach sollte hoffentlich einiges klarer sein, ansonsten kannst du immer noch mit konkreten Fragen kommen.Grüssli
-
^^
Mhm. Ich dacht mir schon das da irgendwas nicht stimmt. Habe die Referenzen mit den Manipulatoren sehr wohl gelesen und auch eingebaut, allerdings auch ohne Erfolg. Und als ich dann die Codes verglichen habe, ist mir aufgefallen das deiner viel länger ist. Habe mir dann auf Grund meiner Misserfolge mit den selbst geschriebenen Codes, gedacht, dass ich irgendetwas wichtiges, was in deinem Code vorkommt übersehen habe bzw. irgendeine wichtige Funktion für mein Vorhaben nicht kenne, und dann eben deinen Code eingefügt und nochmal hier nachgefragt.Naja, habe auf jeden Fall nochmal den Code,mit dem von mir geschrieben "setfill" abgespeichert. Allerdings funktioniert dieser auch nicht. Ich vermute, dass ich die Variable falsch eingesetzt habe oder sowas, da die Variable nicht farbig wird, wie zB Ganzzahlen.....aber ich will nichts falsches sagen ^^
Naja wäre auf jeden Fall nett wenn mir jemand sagen könnte was ich hier falsch gemacht habe...
if (zminute<10) { cout << setfill ('0') << setw (2); cout << zminute; }
P.S.: Finds eig gut, dass du den Code nicht zum Copy&Paste postest, schließlich soll man auch was lernen
-
Bist du sicher, dass du es verstanden hast? Denn wenn du es hättest, wüsstest du zum Beispiel, dass du die if-Abfrage gar nicht mehr benötigst.
Zudem, wenn du wirklich diesen Code hast:cout << setfill ('0') << setw (2); cout << zminute;
Dann sollte zminute in einem zweistelligen Format mit führenden Nullen ausgegeben werden.
Zeig doch die ganze Ausgabe, welche du geschrieben hast (Nur die Ausgabe!). Sag was du bekommst und was du erwartest. Dann können wir nicht nur mögliche Fehler finden, sondern auch sinnvoll helfen
Grüssli
-
Mhm. Also ich bin der Meinung, dass ich das wider anwenden könnte. Aber das mit dem if weglassen habe ich tatsächlich überlesen oder nicht verstanden...kA.
Wenn ich das Programm starte kommt folgendes:
Datum-/Uhrzeitrechner started Beliebige Taste zum Starten druecken! Bitte Starttag eingeben Bitte Startmonat eingeben Bitte Startjahr eingeben Bitte Startstunde eingeben Bitte Startminute eingeben Bitte Additionstage eingeben Bitte Additionsstunden eingeben Bitte Additionsminuten eingeben Enddatum: Starttag+Additionstag.Startmonat.Startjahr Startstunde+Additionsstunde:Startminute+Additionsminute Beliebige Taste zum Beenden druecken!
Beispiel:
Datum-/Uhrzeitrechner started Beliebige Taste zum Starten druecken! enter Bitte Starttag eingeben 1 Bitte Startmonat eingeben 11 Bitte Startjahr eingeben 2008 Bitte Startstunde eingeben 18 Bitte Startminute eingeben 40 Bitte Additionstage eingeben 1 Bitte Additionsstunden eingeben 1 Bitte Additionsminuten eingeben 25 Enddatum: Starttag+Additionstag.Startmonat.Startjahr Startstunde+Additionsstunde:Startminute+Additionsminute 2.11.2008 20:5 Uhr Beliebige Taste zum Beenden druecken! enter
Nja und beim Enddatum liegt das Problem. Da müsste ja eig 20:05 Uhr stehen.
Hier mal mein geschriebener Code:
int main() { cout<<"Datum-/Uhrzeitrechner started"; cout<<"Beliege Taste zum Starten druecken!"; std::cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); std::cin.get(); int tag; int monat; int jahr; int stunde; int minute; cout<<"Bitte Tag eingeben\n"; cin>>tag; cout<<"Bitte Monat eingeben\n"; cin>>monat; cout<<"Bitte Jahr eingeben\n"; cin>>jahr; cout<<"Bitte Stunde eingeben\n"; cin>>stunde; cout<<"Bitte Minute eingeben\n"; cin>>minute; int wtag; int wstunde; int wminute; cout<<"Bitte Weiterbildungstage eingeben\n"; cin>>wtag; cout<<"Bitte Weiterbildungsstunden eingeben\n"; cin>>wstunde; cout<<"Bitte Weiterbildungsminuten eingeben\n"; cin>>wminute; int ztag = (tag+wtag); int zstunde = (stunde+wstunde); int zminute = (minute+wminute); if (zminute>=60) { zstunde++; zminute -=60; } if (zstunde>=24) { zstunde -= 24; ztag++; } cout<<"Weiterbildung endet am: "<<ztag<<"."<<monat<<"."<<jahr<< " um "<<zstunde<<":";cout << setfill ('0') << setw (2); cout << zminute;" Uhr\n\n\n"; std::cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); std::cin.get(); }
Naja. Also der Fehler liegt denk ich mal in:
cout<<"Weiterbildung endet am: "<<ztag<<"."<<monat<<"."<<jahr<< " um "<<zstunde<<":";cout << setfill ('0') << setw (2); cout << zminute;" Uhr\n\n\n";
mfg idk
-
Ich hahe doch gesagt, nur die Ausgabe
Also hätte das hier gereicht:cout << "Weiterbildung endet am: " << ztag << '.' << monat << '.' << jahr << " um " << zstunde << ':' << setfill('0') << setw(2) << zminute << " Uhr\n\n\n";
Ich habe die Sache etwas umformatiert, damit man es überhaupt lesen kann. Aber grundsätzlich passiert daselbe, bis auf den Unterschied, dass bei mir noch der letzte Text ausgegeben wird, also das " Uhr\n\n\n", dies geschieht bei deinem Code nämlich nicht.
Wenn ich zudem die Ausgabe anschaue, welche du anscheinend bekommst, dann stimmt die sowieso irgendwie nicht mit deinem Code überein. Bist du sicher, dass du genau diesen Code verwendest, denn er funktioniert bei mir.
Das if kannst du im übrigen weglassen, weil man mit diesen Befehlen angibt, dass die Weite der Zahl 2 betragen soll und falls sie kleiner als 2 Zeichen benötigt, die restlichen Zeichen davor mit dem Zeichen '0' aufgefüllt werden sollen. Die if Abfrage passiert also automatisch
Grüssli
-
Achso. Ich dachte du meintest alles was mir die Konsole angibt.
mhm. Komisch...aber du hast Recht. Habe den Code nicht einfach kopiert sondern ein klein wenig verändert. Das "uhr" wird tatsächlich nicht ausgegeben. Aber ich habe das nun auch behoben.
Und das für mich verwunderlichste ist, dass mein Code, welcher auf meiner Festplatte liegt, die 0 nicht mit ausgibt. Wenn ich aber nun den Code von hier kopiere und kompilieren lasse, dann wird die 0 ausgegeben....versteh ich irgendwie nicht.^^
Naja. Aber ich hab grade den Code nochmal überarbeitet. Mir wird jetzt die "0" und das "Uhr" ausgegeben.
Läuft jetzt exakt so, wie ich es mir gewünscht hatte. Und das Beste: Dank diesem Thread hab ich schon wieder viel dazu gelernt
zB das ich "System ("Pause")" demnächst besser nichtmehr verwende und ich habe dazu noch "setfill" und "setw" kennengelernt. Zudem werde ich demnächst nochmehr auf die Ordentlichkeit in meinem Code achten.Nochmals besten Dank an alle Poster und für alle Antworten.
Besonders vielen Dank an dich, Dravere
Hast mir echt weitergeholfen. Find ich echt super!Wenns wiedermal Probleme gibt, werde ich mich wieder an dieses Forum wenden. Echt nützlich eine solche Anlaufstelle zu haben.
mit besten Grüßen an die Helfer hier
idk