Was stimmt hier nicht?



  • HI Leute!

    Ich hab hier ein Programm dass den Wochentag berechnen soll. Leider hat das Programm ein Problem mit Wochentagen die im Janur und im Februar liegen. Ich finde leider den Fehler nicht. Laut Angabe stimmen die Bedingungen der if-Schleifen aber. Die Formel zur Berechnung des Wochentags stimmt auch 100%ig. Könnt ihr mir helfen?

    Hier der Code:

    #include<iostream>
    using namespace std;
    
    int tag, m, j, w;
    
    int main()
    {
        cout << "Tag eingeben: ";
        cin >> tag;
    
        cout << endl;
    
        cout << "Monat eingeben: ";
        cin >> m;
    
        cout << endl;
    
        cout << "Jahr eingeben: ";
        cin >> j;
    
        if(m <= 2)
        {
         m = m + 12;
             }
        else
        {
            m;
        }
    
        if(m <= 2)
        {
         j = j - 1;
             }
        else
        {
            j;
        }
    
        w = (tag + (2*m) + ((3*m+3) / 5) + j + (j / 4) - (j / 100) + (j / 400) + 1) % 7;
    
        // cout << "w=" << w << endl;
        cout << endl;
    
        if(w == 0)
        {
         cout << "Der " << tag << "." << m << "." << j << " ist ein Sonntag" << endl;
              }
        else if(w == 1)
        {
         cout << "Der " << tag << "." << m << "." << j << " ist ein Montag" << endl;
              }
        else if(w == 2)
        {
         cout << "Der " << tag << "." << m << "." << j << " ist ein Dienstag" << endl;
              }
        else if(w == 3)
        {
         cout << "Der " << tag << "." << m << "." << j << " ist ein Mittwoch" << endl;
              }
        else if(w == 4)
        {
         cout << "Der " << tag << "." << m << "." << j << " ist ein Donnerstag" << endl;
              }
        else if(w == 5)
        {
         cout << "Der " << tag << "." << m << "." << j << " ist ein Freitag" << endl;
              }
        else if(w == 6)
        {
         cout << "Der " << tag << "." << m << "." << j << " ist ein Samstag" << endl;
              }
    
    system("pause");
    return 0;
    }
    


  • huhu bandchef,

    du solltest Algorithmen kommentieren, dass der Betrachter nachvollziehen kann, was du mit dieser und jener Codezeile bezwecken wolltest... und es somit einfacher ist, dir zu helfen 😉

    mfg dweb



  • Och, hier braucht man keine Kommentare.



  • if(m <= 2)
        {
         m = m + 12;
             }
        else
        {
            m;
        }
    

    OK, der 10.1.2010 ist in Wirklichkeit der 10.13.2009.
    Aaber das hier wird nie eintreffen, weil DU zuerst den Monat auf 13 gesetzt hast und jetzt er nicht mehr <=2 ist.

    if(m <= 2)
        {
         j = j - 1;
             }
        else
        {
            j;
        }
    


  • Und was bedeutet das jetzt @ Volkard?



  • Das hier sind die Bedingungen meiner Aufgabenstellung. Seht ihr unten im Bild. Ich weiß echt nicht was ich da jetzt falsch gemacht hab; ich hab halt die Bedingung in eine if-Schleife umgesetzt...

    Bild http://yfrog.com/6f14831256j

    Danke!



  • Wie wäre es, wenn du für die Ausgabe die Werte der Eingabe benutzt und nur temporäre monat-/jahrvariablen veränderst und nicht den Eingabewert?

    bandchef schrieb:

    Und was bedeutet das jetzt @ Volkard?

    Das du die Abfragen drehen solltes...



  • Was stellst du dir da vor? Was soll ich drehen? Soll ich anstatt <= das >= schreiben? Dann geht zwar der Januar und Februar aber dann fuckts bei den anderen Monaten und zusätzlich stimmts dann mit meiner Aufgabenstellung nicht überein...



  • So geht jetzt der Januar und der Februar aber dafür die höheren Monate nicht...

    if(m <= 2)
        {
         M = m + 12;
             }
        else
        {
            m;
        }
    
        if(m <= 2)
        {
         J = j - 1;
             }
        else
        {
            j;
        }
    
        w = (tag + (2*M) + ((3*M+3) / 5) + J + (J / 4) - (J / 100) + (J / 400) + 1) % 7;
    


  • Du hast immernoch den von Volkhard genannten Fehler. Du muss die Jahre vor dem Monat abfragen.



  • Wie wäre es denn, einfach Alles ein wenig zu entzerren:

    bool IsLeapyear(int year)
    {
    	if(year<1) return false;
    	if(year%4) return(false);
    	if(year<=1582) return(true);
    	if(year%100) return(true);
    	if(year%400) return(false);
    	return(true);
    }
    int DaysPerMonth(int month, int year)
    {
    	switch(month)
    	{
    		case 1:
    		case 3:
    		case 5:
    		case 7:
    		case 8:
    		case 10:
    		case 12:
    			return(31);
    		case 4:
    		case 6:
    		case 9:
    		case 11:
    			return(30);
    		case 2:
    			return(28+IsLeapyear(year));
    		default:
    			return 0;
    	}
    }
    size_t DaysPast(int day, int month, int year)
    {
    	size_t ret=0;
    	int x=1;
    	while(x<year)
    		ret+=365+IsLeapyear(x++);
    	x=1;
    	while(x<month)
    		ret+=DaysPerMonth(x++,year);
    	ret+=day-1;
    
    	if(ret>577736)
    		ret-=10;
    
    	return ret;
    }
    std::string GetWeekdayName(int day, int month, int year) 
    {
            // (Edit) Erklärung: Der 1.1.01 war ein Samstag
    	switch((DaysPast(day,month,year)+5)%7)
    	{
    		case 0: return ("Montag");
    		case 1: return ("Dienstag");
    		case 2: return ("Mittwoch");
    		case 3: return ("Donnerstag");
    		case 4: return ("Freitag");
    		case 5: return ("Samstag");
    		case 6: return ("Sonntag");
    		default: return (""); // Compiler beruhigen
    	}
    }
    
    int main()
    {
    	std::cout << GetWeekdayName(14,11,2010) << endl;
    }
    


  • bandchef schrieb:

    Und was bedeutet das jetzt @ Volkard?

    Ich fand es klar ausgedrückt. Wenn Du das noch nicht vestehst, will ich lieber, daß Du die Punkte für die Hausübung nicht bekommst.



  • Vicious Falcon schrieb:

    bool IsLeapyear(int year)
    {
    	if(year<1) return false;//Warum?
    

    Vicious Falcon schrieb:

    default:
    			return 0;//Warum?
    

    Vicious Falcon schrieb:

    size_t/*Warum?*/ DaysPast(int day, int month, int year)
    {
    

    Vicious Falcon schrieb:

    std::string/*Warum?*/ GetWeekdayName(int day, int month, int year) 
    {
    	switch((DaysPast(day,month,year)+5)%7)//Warum kein Array?
    


  • volkard schrieb:

    Vicious Falcon schrieb:

    bool IsLeapyear(int year)
    {
    	if(year<1) return false;//Warum? // Gute Frage, müßte sonst year=-year sein?
    

    Vicious Falcon schrieb:

    default:
    			return 0;//Warum? // Compiler beruhigen, sonst exception werfen?
    

    Vicious Falcon schrieb:

    size_t/*Warum?*/ DaysPast(int day, int month, int year) 
    // Für die Differenz zweier beliebiger Daten (bspw. heute und einem zukünftigem Datum), wäre es besser wie im Originalen int zu nehmen, da es aber ein typedef war, habe ich es ohne Überlegung geändert.
    {
    

    Vicious Falcon schrieb:

    std::string/*Warum?*/ GetWeekdayName(int day, int month, int year) // bei mir steht const TCHAR* , hab's rausgenommen wegen der char und Pointerallergie im Forum, bei mir steht auch bspw. _T("Montag")
    {
    	switch((DaysPast(day,month,year)+5)%7)//Warum kein Array? // was meinst du damit?
    

    Besser wäre es natürlich, den Monat direkt als enum darzustellen. Die Funktionen sind auch keine freien Funktionen, sondern eigentlich Klassenmember. Mit diesem enum wäre die Initialisierung noch sicherer.



  • bool IsLeapyear(int year)
    {
    	if(year<1) return false;//Warum? // Gute Frage, müßte sonst year=-year sein?
    

    Auch nicht. Schon meistens Quatsch, für so alte Daten den Tag wissen zu wollen. Ich würde es verbieten. Zur Not assert.

    default:
    			return 0;//Warum? // Compiler beruhigen, sonst exception werfen?
    

    Garbage in, garbage out. Gar nicht auf Fehler prüfen. Dafür den großen case-Fall wegmachen.

    size_t/*Warum?*/ DaysPast(int day, int month, int year) 
    // Für die Differenz zweier beliebiger Daten (bspw. heute und einem zukünftigem Datum), wäre es besser wie im Originalen int zu nehmen, da es aber ein typedef war, habe ich es ohne Überlegung geändert.
    {
    

    unsigned int oder int? Deine Wahl. Vielleicht int32_t? Aber nicht size_t! Was hat das mit Größen zu tun? Warum soll ich azf 64-Bit-Systemen hier einen 64-bitter zurückgeben?

    std::string/*Warum?*/ GetWeekdayName(int day, int month, int year) // bei mir steht const TCHAR* , hab's rausgenommen wegen der char und Pointerallergie im Forum, bei mir steht auch bspw. _T("Montag")
    

    Naja, hier habe ich eine std::string-Allergie.

    switch((DaysPast(day,month,year)+5)%7)//Warum kein Array? // was meinst du damit?
    
    static TCHAR const* names[7]={_T"Montag",_T"Dienstag",...
    return names[(DaysPast(day,month,year)+5)%7];
    

    Besser wäre es natürlich, den Monat direkt als enum darzustellen. Die Funktionen sind auch keine freien Funktionen, sondern eigentlich Klassenmember. Mit diesem enum wäre die Initialisierung noch sicherer.

    Jo. Oder nur int. Und jeder darf ja

    cout<<GetWeekdayName(GetWeekdayName(1,1,1950))<<'\n';
    

    machen, wenn er einen Text braucht.



  • bandchef schrieb:

    Das hier sind die Bedingungen meiner Aufgabenstellung. Seht ihr unten im Bild. Ich weiß echt nicht was ich da jetzt falsch gemacht hab; ich hab halt die Bedingung in eine if-Schleife umgesetzt...

    Bild http://yfrog.com/6f14831256j

    Danke!

    In der Aufgabenstellung gibt es monat und m, bzw. jahr und j. Wenn du dich daran orientierst, sollte es funktionieren.



  • Ich hab mir jetzt nochmal Gedanken dazu gemacht insbesondere zu Mannis Antwort. Ich hab jetzt die Jahresabfrage vor der Monatsabfrage platziert und die Aufgabenstellung genauer umgesetzt. Leider funktionierts immer noch nicht. Vielleicht kannst du, Manni66, nochmal genauer drauf eingehen. Achja und ich bekomme KEINE Punkte auf diese Hausübung!!! Sie ist mehr oder weniger freiwillig...

    if(monat  <= 2)
        {
         j = jahr - 1;
             }
        else
        {
            m = monat;
        }
    
        if(monat <= 2)
        {
         m = monat + 12;
             }
        else
        {
           m = monat;
        }
    
        w = (tag + (2*m) + ((3*m+3) / 5) + j + (j / 4) - (j / 100) + (j / 400) + 1) % 7;
    


  • Kann man dir dann auch eine andere Lösung vorschlagen?

    Außerdem sollte das nicht j = jahr heißen?

    if(monat  <= 2)
        {
         j = jahr - 1;
             }
        else
        {
            m = monat;
        }
    


  • Sorry abe deinen letzten Satz

    Kann man dir dann auch eine andere Lösung vorschlagen?

    hab ich nicht verstanden. Natürlich kann man das, aber es sollte nicht an der Aufgabenstellung vorbei gehen.

    Außerdem sollte das nicht j = jahr heißen?

    In meiner Aufgabe steht doch, dass ich jahr - 1 rechnen soll, wenn der Monat kleinergleich 2 ist... Weiß nicht was daran falsch sein soll...



  • Danke Leute für eure Hilfe, ich hab den Fehler jetzt selber gefunden. Es war ein Fehler in der Ausgabe!


Anmelden zum Antworten