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 Bereich 😉

    Zu 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


  • Administrator

    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 auf system . Wie man das automatische schliessen verhindert, erfährst du hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-111042.html
    Wieso system schlecht ist, steht hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-39453.html

    Zudem 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 die system("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ücken 🙂

    Vielen 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


  • Administrator

    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 und setfill .
    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 😉


  • Administrator

    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


  • Administrator

    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


Log in to reply