Wochentagsberechnung nach Gauß produziert "segmentation-faults"



  • DirkB schrieb:

    wob schrieb:
    2. Was soll der Komma-Operator hier bedeuten:
    wob wollte nichts über die Gaußklammern wissen.
    Du solltest darüber nachdenken, warum du da Kommas , stehen hast.
    Der Kommaoperator führt bei C++ meist für Missverständnisse. Gerade bei Anfängern.

    Und mit deiner Antwort hast du beiesen, dass du gar nicht weißt, wozu der da ist.

    Darum einfacher: Mit welchem Dezimaltrennzeichen werden Fließkommazahlen in C++ angegeben?

    Schlangemensch schrieb:

    Bei dem hier: ((int) (2, 6 * julMonat - 0, 2)) + 1; Was ist denn da dein erwartetes Ergbenis?

    willst du rechnen
    x = 2,6 * y - 0,2 + 1 ?
    In C++ nutzt man den "." als Dezimalseparator, also
    x= 2.6 * y - 0.2 + 1

    Klar, dummer Fehler :p

    Ich schreib den Code mal um und melde mich später. Danke erstmal 👍



  • Schlangenmensch schrieb:

    Philipp2706 schrieb:

    Okay ja stimmt. Kann ich stattdessen
    C++:
    if (cin.fail()&&cin.eof())
    nehmen?

    Das ändert nichts daran, dass der Ausdruck zu false wird, wenn cin.fail()==false, du also mit der Eingabe 0a0a0 trotzdem nicht den if-Zweig kommst.

    soo...
    ich habe den ganzen Eingabeteil überarbeitet. Jetzt müssten alle Fehler abgedeckt sein 🙂 🙂 Gibt es da noch was zu bemängeln?

    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    
    /* 
     */
    
    #include <iostream>
    #include <string> 
    #include <sstream>  
    #include <vector>
    #include <cmath>  
    #include <stdexcept>
    
    using namespace std;
    
    //Wochentage enum
    enum WochentageTyp {
        Sonntag, Montag, Dienstag, Mittwoch,
        Donnerstag, Freitag, Samstag
    };
    typedef WochentageTyp wochentage;
    string wochentageStr [] = {"Sonntag", "Montag", "Dienstag", "Mittwoch",
        "Donnerstag", "Freitag", "Samstag"};
    
    //Funktionen
    int wochentagDatum(int eingabeMonat, int eingabeJahr, int eingabeTag);
    vector<int> stellenAbtrennen(int eingabeJahr);
    wochentage wochentagErsterJanuar(int jahresZahlGauss);
    int julKalenderUmrechnen(int eingabeMonat);
    bool pruefenInteger(string eingabe);
    
    /*
     * 
     */
    int main(int argc, char** argv) {
        cout << "Immerwährender Kalender" << endl;
    
        string eingabeZeile;
        string eingabeTagStr;
        string eingabeMonatStr;
        string eingabeJahrStr;
        int eingabeTagInt, eingabeMonatInt, eingabeJahrInt;
    
        bool schleifeVerlassen = false;
        while (!schleifeVerlassen) {
            cout << "Bitte geben Sie ein Datum ein" << endl;
            //Eingabe des Datums
            string eingabeZeile;
            getline(cin, eingabeZeile);
            eingabeTagStr = eingabeZeile.substr(0, 2);
            eingabeMonatStr = eingabeZeile.substr(3, 2);
            eingabeJahrStr = eingabeZeile.substr(6, 4);
            //PrüfenInteger jeweils aufrufen
            bool boolVerknuepft =
                    (pruefenInteger(eingabeTagStr)) &&
                    (pruefenInteger(eingabeMonatStr)) &&
                    (pruefenInteger(eingabeJahrStr));
    
            if ((!("." == string(1, eingabeZeile[2]) &&
                    !("." == string(1, eingabeZeile[5]) == 0))) &&
                    (boolVerknuepft == 0)) {
                cout << "#Punktsetzung falsch" << endl;
                cout << "#Keine Symbole, Buchstaben oder Kommazahlen zulässig" << endl;
                continue;
            }
    
            if (!("." == string(1, eingabeZeile[2]) &&
                    !("." == string(1, eingabeZeile[5]) == 0))) {
                cout << "#Punktsetzung falsch" << endl;
                continue;
            }
    
            if (boolVerknuepft == 0) {
                cout << "#Keine Symbole, Buchstaben oder Kommazahlen zulässig" << endl;
                continue;
            }
    
            if (boolVerknuepft == 1) {
                eingabeTagInt = stoi(eingabeTagStr);
                eingabeMonatInt = stoi(eingabeMonatStr);
                eingabeJahrInt = stoi(eingabeJahrStr);
            }
    
            if (eingabeTagInt > 31 || eingabeMonatInt > 12 ||
                    (eingabeJahrInt < 1000 && eingabeJahrInt > 9999)) {
                cout << "#Unzulässige Werte" << endl;
                continue;
            }
    
            if (!(cin.fail() && cin.eof())&&((!(eingabeJahrInt % 4) &&
                    (eingabeJahrInt % 100)) || !(eingabeJahrInt % 400))) {
                cout << "#Das eingegebene Jahr ist ein Schaltjahr" << endl;
            }
    
            cout << "Eingabe korrekt" << endl;
            break;
        }
    
        //Julianischer Monat Umrechnung
        int julMonat = julKalenderUmrechnen(eingabeMonatInt);
        //Ausgabe Text für die erste Funktion
        cout << "--------------------------------------------" << endl <<
                "Der Wochentag des 1. Januars des Jahres " << eingabeJahrInt <<
                " ist ein "
                << wochentageStr [wochentagErsterJanuar(eingabeJahrInt)] << endl;
        //Zweite Funktion
        cout << "Der Wochentag des ersten Tages dieses Monats ist ein " <<
                wochentageStr[wochentagDatum(julMonat, eingabeJahrInt, 1)] << endl
                << "Der Wochentag des eingegebenen Datum ist ein  " <<
                wochentageStr[wochentagDatum(julMonat, eingabeJahrInt, eingabeTagInt)]
                << endl;
    }
    
    //Zahl des Monats in julianischen Kalender umrechnen
    int julKalenderUmrechnen(int eingabeMonat) {
        int monateJul;
        switch (eingabeMonat) {
            case 1: monateJul = 11;
                break;
            case 2: monateJul = 12;
                break;
            case 3: monateJul = 1;
                break;
            case 4: monateJul = 2;
                break;
            case 5: monateJul = 3;
                break;
            case 6: monateJul = 4;
                break;
            case 7: monateJul = 5;
                break;
            case 8: monateJul = 6;
                break;
            case 9: monateJul = 7;
                break;
            case 10: monateJul = 8;
                break;
            case 11: monateJul = 9;
                break;
            case 12: monateJul = 10;
                break;
        }
        return monateJul;
    }
    
    bool pruefenInteger(string eingabe) {
    
        char zeicheni;
        int ascii;
    
        for (int i = 0; i <= eingabe.length(); i++) {
            zeicheni = eingabe[i];
            ascii = int(zeicheni);
            if (ascii < 58 && i >= eingabe.length()) {
                return true;
            }
            if (ascii > 58) return false;
        }
    }
    
    wochentage wochentagErsterJanuar(int jahresZahlGauss) {
        //eingabeJahresZahl=vierstellige Jahreszahl
        //Gaußsche Wochentagsformel
        wochentage gaussTag = (wochentage) ((1 + 5 * ((jahresZahlGauss - 1) % 4)
                + 4 * ((jahresZahlGauss - 1) % 100) +
                6 * ((jahresZahlGauss - 1) % 400)) % 7);
        return gaussTag;
    }
    
    // Georg Glaeser Algorithmus
    int wochentagDatum(int julMonat, int eingabeJahr, int eingabeTag) {
    
        vector<int> pos;
        vector<int> posVorjahr;
    
        pos = stellenAbtrennen(eingabeJahr);
        posVorjahr = stellenAbtrennen(eingabeJahr - 1);
    
        int letzteStellen = pos[0];
        int ersteStellen = pos[1];
    
        if (julMonat == 1 || julMonat == 2) {
            letzteStellen = posVorjahr [0];
            ersteStellen = posVorjahr [1];
        }
    
        int gaussKlammernAufrunden = ((int) (2.6 * julMonat - 0.2)) + 1;
        int wochentagMonatsErster = ((eingabeTag + gaussKlammernAufrunden
                + letzteStellen + (letzteStellen / 4) +
                (ersteStellen / 4) - 2 * ersteStellen) % 7);
    
        return wochentagMonatsErster;
    }
    
    vector<int> stellenAbtrennen(int eingabeJahr) {
        vector<int> positionen;
        int erstenStellen = eingabeJahr / 100;
        positionen.push_back(erstenStellen);
        int letzteStellen = eingabeJahr % 100;
        positionen.push_back(letzteStellen);
    
        return positionen;
    }
    

    Ich bekomme allerdings immer noch diese Segmention-Faults. Ich bin mir ziemlich sicher dass es irgendwie an dem Vektor liegen muss. Aber ich komme nicht darauf was falsch sein soll 😕 eventuell passt die Dimension von dem übergebenen Vektor nicht zu dem Vektor der den zu übergebenden Vektor speichern soll 😕 😕



  • Grade nur kurz, weil vom Handy.

    Zwei Sachen:

    Punkt Segfault:

    bool pruefenInteger(string eingabe) {
    
        char zeicheni;
        int ascii;
    
        for (int i = 0; i <= eingabe.length(); i++) {
            zeicheni = eingabe[i];
            ascii = int(zeicheni);
            if (ascii < 58 && i >= eingabe.length()) {
                return true;
            }
            if (ascii > 58) return false;
        }
    }
    

    Was wird denn im letzten Schleifen Durchlauf an zeicheni zugewiesen?

    Punkt Eingabe Überprüfung:
    Was passiert, wenn die Eingabe z.B. Nur 3 Zeichen lang ist.



  • Bevor du weitermachst, solltest du unbedingt und immer Compilerwarnungen anschalten!

    Hier:

    test.cpp:65:23: warning: suggest parentheses around comparison in operand of ‘==’ [-Wparentheses]
    !("." == string(1, eingabeZeile[5]) == 0))) &&
    ^
    test.cpp:73:23: warning: suggest parentheses around comparison in operand of ‘==’ [-Wparentheses]
    !("." == string(1, eingabeZeile[5]) == 0))) {
    ^
    test.cpp: At global scope:
    test.cpp:40:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
    int main(int argc, char** argv) {
    ^
    test.cpp:40:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
    int main(int argc, char** argv) {
    ^
    test.cpp: In function ‘bool pruefenInteger(std::__cxx11::string)’:
    test.cpp:158:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for (int i = 0; i <= eingabe.length(); i++) {
    ^
    test.cpp:161:29: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    if (ascii < 58 && i >= eingabe.length()) {
    ^
    test.cpp:166:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^

    Besonders wichtig dabei sind die ersten beiden Meldungen und die letzte Meldung.

    Was willst du mit a==b==0 erreichen? Und wozu willst du ein char in einen String wandeln? Willst du nicht sowas wie if (eingabeZeile[5] == '.') schreiben? Außerdem: bist du sicher, dass es eingabeZeile[5] überhaupt gibt? Was ist, wenn der Benutzer weniger Zeichen eingibt?

    Bei der letzten Warnung: stelle immer sicher, dass eine Funktion, die etwas returnen soll, auch etwas returnt!

    Zu den anderen: String-Längen sind unsigned, hier kannst du also z.B. size_t i statt int i schreiben.

    Um die beiden unused Parameter musst du dich nicht unbedingt kümmern -> oder schreib einfach int main() wenn du argc/argv nicht benötigst. Oder lass einfach die Namen weg oder kommentiere sie aus, z.B. so: int main(int /*argc*/, char** /*argv*/) .

    Weitere Kommentare (erster Blick, absolut unvollständig):

    • pruefenInteger : was ist "58"? Irgendwie verstehe ich die gesamte Funktion nicht. Willst du nicht sowas wie "isdigit" verwenden?
      - meinst du nicht, dass man julKalenderUmrechnen einfacher formulieren könnte?
      - wozu die Variable schleifeVerlassen , die eh immer false ist?


  • Schlangenmensch schrieb:

    Punkt Eingabe Überprüfung:
    Was passiert, wenn die Eingabe z.B. Nur 3 Zeichen lang ist.

    ist behoben

    if (eingabeTag > 31 || eingabeMonat > 12 ||
    			eingabeJahr < 1000 || eingabeJahr > 9999) {
    			cout << "#Unzulässige Werte" << endl;
    			continue;
    		}
    

    wob schrieb:

    Was willst du mit a==b==0 erreichen? Und wozu willst du ein char in einen String wandeln? Willst du nicht sowas wie if (eingabeZeile[5] == '.') schreiben?

    ja stimmt. Weiß ich auch nicht mehr so genau was ich mir dabei gedacht habe 😃

    wob schrieb:

    Außerdem: bist du sicher, dass es eingabeZeile[5] überhaupt gibt? Was ist, wenn der Benutzer weniger Zeichen eingibt?

    Ich würde ja vorher testen ob die eingegebene Zahl vierstellig ist.

    wob schrieb:

    - pruefenInteger: was ist "58"? Irgendwie verstehe ich die gesamte Funktion nicht. Willst du nicht sowas wie "isdigit" verwenden?

    Oh man 😡 hätte ich "isdigit" vorher gekannt, hätte ich mir einige Stunden Arbeit ersparen können 😞

    wob schrieb:

    Zu den anderen: String-Längen sind unsigned, hier kannst du also z.B. size_t i statt int i schreiben.

    geändert

    wob schrieb:

    - meinst du nicht, dass man julKalenderUmrechnen einfacher formulieren könnte?
    - wozu die Variable schleifeVerlassen, die eh immer false ist?

    auch geändert
    ...
    Ich habe den Code jetzt mit Visual Studio analysiert und es wurden keine Fehler festgestellt.

    Die segmentation faults sind weg aber das Programm wird mit "Code 0" beendet. 😞

    /*
    * To change this license header, choose License Headers in Project Properties.
    * To change this template file, choose Tools | Templates
    * and open the template in the editor.
    */
    
    /*
    */
    
    #include <iostream>
    #include <string> 
    #include <sstream>  
    #include <vector>
    #include <cmath>  
    #include <stdexcept>
    #include <iostream>
    #include <algorithm> // for copy
    #include <iterator> // for ostream_iterator
    #include <vector>
    
    using namespace std;
    
    //Wochentage enum
    enum WochentageTyp {
    	Sonntag, Montag, Dienstag, Mittwoch,
    	Donnerstag, Freitag, Samstag
    };
    typedef WochentageTyp wochentage;
    string wochentageStr[] = { "Sonntag", "Montag", "Dienstag", "Mittwoch",
    "Donnerstag", "Freitag", "Samstag" };
    
    //Funktionen
    int wochentagDatum(int eingabeMonat, int eingabeJahr, int eingabeTag);
    vector<int> stellenAbtrennen(int eingabeJahr);
    wochentage wochentagErsterJanuar(int jahresZahlGauss);
    int julKalenderUmrechnen(int eingabeMonat);
    
    /*
    *
    */
    int main(int argc, char** argv) {
    	cout << "Immerwährender Kalender" << endl;
    
    	int eingabeTag, eingabeMonat, eingabeJahr;
    	char punkt1, punkt2;
    	do{
    		cout << "Bitte geben Sie ein Datum ein" << endl;
    		//Eingabe des Datums
    		cin >> eingabeTag >> punkt1 >> eingabeMonat >> punkt2 >> eingabeJahr;
    		//Prüfen ob Integer
    		bool boolVerknuepft =
    			(isdigit(eingabeTag)) &&
    			(isdigit(eingabeMonat)) &&
    			(isdigit(eingabeJahr));
    
    		if ((!(punkt1 == '.') &&
    			!(punkt2 == '.')) &&
    			(punkt2 == 0)) {
    			cout << "#Punktsetzung falsch" << endl;
    			cout << "#Keine Symbole, Buchstaben oder Kommazahlen zulässig" << endl;
    			continue;
    		}
    
    		if (!(punkt1 == '.') &&
    			!(punkt2 == '.')) {
    			cout << "#Punktsetzung/Format falsch" << endl;
    			continue;
    		}
    
    		if (boolVerknuepft == 1) {
    			cout << "#Keine Symbole, Buchstaben oder Kommazahlen zulässig" << endl;
    			continue;
    		}
    
    		if (eingabeTag > 31 || eingabeMonat > 12 ||
    			eingabeJahr < 1000 || eingabeJahr > 9999) {
    			cout << "#Unzulässige Werte" << endl;
    			continue;
    		}
    
    		if ((eingabeTag > 31 || eingabeMonat > 12 ||
    			eingabeJahr < 1000 || eingabeJahr > 9999) &&
    			((!(eingabeJahr % 4) &&
    			(eingabeJahr % 100)) || !(eingabeJahr % 400))) {
    			cout << "#Das eingegebene Jahr ist ein Schaltjahr" << endl;
    		}
    
    		cout << "Eingabe korrekt" << endl;
    		break;
    	} while (cin);
    
    	//Julianischer Monat Umrechnung
    	int julMonat = julKalenderUmrechnen(eingabeMonat);
    	//Ausgabe Text für die erste Funktion
    	cout << "--------------------------------------------" << endl <<
    		"Der Wochentag des 1. Januars des Jahres " << eingabeJahr <<
    		" ist ein "
    		<< wochentageStr[wochentagErsterJanuar(eingabeJahr)] << endl;
    	//Zweite Funktion
    	cout << "Der Wochentag des ersten Tages dieses Monats ist ein " <<
    		wochentageStr[wochentagDatum(julMonat, eingabeJahr, 1)] << endl
    		<< "Der Wochentag des eingegebenen Datum ist ein  " <<
    		wochentageStr[wochentagDatum(julMonat, eingabeJahr, eingabeTag)]
    		<< endl;
    }
    
    //Zahl des Monats in julianischen Kalender umrechnen
    int julKalenderUmrechnen(int eingabeMonat) {
    	int monateJul;
    	if (eingabeMonat == 1 || eingabeMonat == 2) {monateJul = eingabeMonat + 10; return monateJul;}
    	else {monateJul = eingabeMonat + -2; return monateJul;}
    }
    
    wochentage wochentagErsterJanuar(int jahresZahlGauss) {
    	//eingabeJahresZahl=vierstellige Jahreszahl
    	//Gaußsche Wochentagsformel
    	wochentage gaussTag = (wochentage)((1 + 5 * ((jahresZahlGauss - 1) % 4)
    		+ 4 * ((jahresZahlGauss - 1) % 100) +
    		6 * ((jahresZahlGauss - 1) % 400)) % 7);
    	return gaussTag;
    }
    
    // Georg Glaeser Algorithmus
    int wochentagDatum(int julMonat, int eingabeJahr, int eingabeTag) {
    
    	vector<int> pos(stellenAbtrennen(eingabeJahr));
    	vector<int> posVorjahr(stellenAbtrennen(eingabeJahr - 1));
    
    	int* arrPos = pos.data();
    	int* arrPosVorjahr = posVorjahr.data();
    
    	int letzteStellen = arrPos[0];
    	int ersteStellen = arrPos[1];
    
    	if (julMonat == 1 || julMonat == 2) {
    		letzteStellen = arrPosVorjahr[0];
    		ersteStellen = arrPosVorjahr[1];
    	}
    	int gaussKlammernAufrunden = ((int)(2.6 * julMonat - 0.2)) + 1;
    	int wochentagMonatsErster = ((eingabeTag + gaussKlammernAufrunden
    		+ letzteStellen + (letzteStellen / 4) +
    		(ersteStellen / 4) - 2 * ersteStellen) % 7);
    
    	return wochentagMonatsErster;
    }
    
    vector<int> stellenAbtrennen(int eingabeJahr) {
    	vector<int> positionen;
    	int erstenStellen = eingabeJahr / 100;
    	positionen.push_back(erstenStellen);
    	int letzteStellen = eingabeJahr % 100;
    	positionen.push_back(letzteStellen);
    
    	return positionen;
    }
    


  • Philipp2706 schrieb:

    Die segmentation faults sind weg aber das Programm wird mit "Code 0" beendet. 😞

    Was erwartest du denn, wie dein Programm beendet wird?

    Was soll while(cin) bewirken? Warum springst du vor der while Überprüfung mit break aus der Schleife?



  • Philipp2706 schrieb:

    int wochentagDatum(int julMonat, int eingabeJahr, int eingabeTag) {
    	vector<int> pos(stellenAbtrennen(eingabeJahr));
    	int* arrPos = pos.data();
    	int letzteStellen = arrPos[0];
    	int ersteStellen = arrPos[1];
    

    Wer hat dir denn so beigebracht?! Wozu der Umweg über int*, womit du die Vorteile des vectors gleich wieder wegschmeißt.

    Sollte es nicht besser heißen:

    int wochentagDatum(int julMonat, int eingabeJahr, int eingabeTag) {
    	auto pos = stellenAbtrennen(eingabeJahr);
    	// irgendeine Art von ensure(pos.size() > 1) 
    	int letzteStellen = pos[0];
    	int ersteStellen = pos[1];
    


  • Warum überhaupt eine Funktion für eingabeJahr%100 bzw. eingabeJahr/100 ?
    Dann doch lieber zwei inline-Funktionen für Jahre und Jahrunderte.



  • DirkB schrieb:

    Warum überhaupt eine Funktion für eingabeJahr%100 bzw. eingabeJahr/100 ?
    Dann doch lieber zwei inline-Funktionen für Jahre und Jahrunderte.

    So habe ich es jetzt auch gemacht. Ich habe zu kompliziert gedacht und habe es sehr unterschätzt einen Vektor an eine Funktion zu übergeben.
    Ich bin auf die Idee gekommen weil ich mit substring anstelle von % und / gearbeitet habe um an die ersten und letzten Stellen der Jahreszahl zu kommen.
    Da hatte ich viel Code und wollte den Code nicht zweimal da stehen haben.

    Schlangenmensch schrieb:

    Was soll while(cin) bewirken? Warum springst du vor der while Überprüfung mit break aus der Schleife?

    Das break habe ich vergessen zu löschen, aber eigentlich funktioniert while (cin) doch. (Vorausgesetzt das Programm würde sich nicht beenden).

    Schlangenmesch schrieb:

    Philipp2706 schrieb:

    Die segmentation faults sind weg aber das Programm wird mit "Code 0" beendet. 😞

    Was erwartest du denn, wie dein Programm beendet wird?

    Die segmentation faults sind doch nicht weg 😞 Visual Studio zweigt mir "Code 0" und netbeans zeigt immer noch das selbe 😞

    Ich habe vermutet dass es an dem Vektor liegt der von der Funktion zurückgegeben wird aber das kann es ja jetzt auch nicht mehr sein.

    Jetzt habe ich die Formel von "int wochentagMonatsErster" in Verdacht, aber ich sehe nicht was daran so einen Fehler verursachen könnte.

    Ich bin echt ratlos so langsam 😕

    #include <iostream>
    #include <string> 
    #include <sstream>  
    #include <vector>
    #include <cmath>  
    #include <stdexcept>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    //Wochentage enum
    enum WochentageTyp {
    	Sonntag, Montag, Dienstag, Mittwoch,
    	Donnerstag, Freitag, Samstag
    };
    typedef WochentageTyp wochentage;
    string wochentageStr[] = { "Sonntag", "Montag", "Dienstag", "Mittwoch",
    "Donnerstag", "Freitag", "Samstag" };
    
    //Funktionen
    int wochentagDatum(int eingabeMonat, int eingabeJahr, int eingabeTag);
    wochentage wochentagErsterJanuar(int jahresZahlGauss);
    int julKalenderUmrechnen(int eingabeMonat);
    inline int erstenStellen(int eingabeJahr);
    inline int letzteStellen(int eingabeJahr);
    
    /*
    *
    */
    int main(int argc, char** argv) {
    	cout << "Immerwährender Kalender" << endl;
    
    	int eingabeTag, eingabeMonat, eingabeJahr;
    	char punkt1, punkt2;
    
    	do{
    		cout << "Bitte geben Sie ein Datum ein" << endl;
    		//Eingabe des Datums
    		cin >> eingabeTag >> punkt1 >> eingabeMonat >> punkt2 >> eingabeJahr;
    		//Prüfen ob Integer
    		bool boolVerknuepft =
    			isdigit(eingabeTag) &&
    			isdigit(eingabeMonat) &&
    			isdigit(eingabeJahr);
    
    		if ((!(punkt1 == '.') &&
    			!(punkt2 == '.')) &&
    			(punkt2 == 0)) {
    			cout << "#Punktsetzung falsch" << endl;
    			cout << "#Keine Symbole, Buchstaben oder Kommazahlen zulässig" << endl;
    			continue;
    		}
    
    		if (!(punkt1 == '.') &&
    			!(punkt2 == '.')) {
    			cout << "#Punktsetzung/Format falsch" << endl;
    			continue;
    		}
    
    		if (boolVerknuepft == 1) {
    			cout << "#Keine Symbole, Buchstaben oder Kommazahlen zulässig" << endl;
    			continue;
    		}
    
    		if (eingabeTag > 31 || eingabeMonat > 12 ||
    			eingabeJahr < 1000 || eingabeJahr > 9999) {
    			cout << "#Unzulässige Werte" << endl;
    			continue;
    		}
    
    		if ((eingabeTag > 31 || eingabeMonat > 12 ||
    			eingabeJahr < 1000 || eingabeJahr > 9999) &&
    			((!(eingabeJahr % 4) &&
    			(eingabeJahr % 100)) || !(eingabeJahr % 400))) {
    			cout << "#Das eingegebene Jahr ist ein Schaltjahr" << endl;
    		}
    
    		cout << "Eingabe korrekt" << endl;
    		break;
    	} while (cin);
    
    	//Julianischer Monat Umrechnung
    	int julMonat = julKalenderUmrechnen(eingabeMonat);
    	//Ausgabe Text für die erste Funktion
    	cout << "--------------------------------------------" << endl <<
    		"Der Wochentag des 1. Januars des Jahres " << eingabeJahr <<
    		" ist ein "
    		<< wochentageStr[wochentagErsterJanuar(eingabeJahr)] << endl;
    	//Zweite Funktion
    	cout << "Der Wochentag des ersten Tages dieses Monats ist ein " <<
    		wochentageStr[wochentagDatum(julMonat, eingabeJahr, 1)] << endl
    		<< "Der Wochentag des eingegebenen Datum ist ein  " <<
    		wochentageStr[wochentagDatum(julMonat, eingabeJahr, eingabeTag)]
    		<< endl;
    }
    
    //Zahl des Monats in julianischen Kalender umrechnen
    int julKalenderUmrechnen(int eingabeMonat) {
    	int monateJul;
    	if (eingabeMonat == 1 || eingabeMonat == 2) {monateJul = eingabeMonat + 10; return monateJul;}
    	else {monateJul = eingabeMonat + -2; return monateJul;}
    }
    
    wochentage wochentagErsterJanuar(int jahresZahlGauss) {
    	//eingabeJahresZahl=vierstellige Jahreszahl
    	//Gaußsche Wochentagsformel
    	wochentage gaussTag = (wochentage)((1 + 5 * ((jahresZahlGauss - 1) % 4)
    		+ 4 * ((jahresZahlGauss - 1) % 100) +
    		6 * ((jahresZahlGauss - 1) % 400)) % 7);
    	return gaussTag;
    }
    
    // Georg Glaeser Algorithmus
    
    	int wochentagDatum(int julMonat, int eingabeJahr, int eingabeTag) {
    		int letzteStellenVar = letzteStellen(eingabeJahr);
    		int ersteStellenVar = erstenStellen(eingabeJahr);
    		int vorjahr = eingabeJahr - 1;
    
    	if (julMonat == 1 || julMonat == 2) {
    		letzteStellenVar = letzteStellen(vorjahr);
    		ersteStellenVar = erstenStellen(vorjahr);
    	}
    	int gaussKlammernAufrunden = ((int)(2.6 * julMonat - 0.2)) + 1;
    	int wochentagMonatsErster = ((eingabeTag + gaussKlammernAufrunden
    		+ letzteStellenVar + (letzteStellenVar / 4) +
    		(ersteStellenVar / 4) - 2 * ersteStellenVar) % 7);
    
    	return wochentagMonatsErster;
    }
    
    	inline int erstenStellen(int eingabeJahr)
    	{
    		int erstenStellen = eingabeJahr / 100;
    		return erstenStellen;
    	}
    	inline int letzteStellen(int eingabeJahr)
    	{
    		int letzteStellen = eingabeJahr % 100;
    		return letzteStellen;
    	}
    


  • Ein Grund in deinem Programm ein Segmentation Fault zu liefern ist bei Zugriff auf das Array wochentageStr,
    wenn der Index falsch ist.

    Lass dir doch mal innerhalb der Funktionen wochentagErsterJanuar und wochentagDatum den Rückgabewert ausgeben (mit cout)
    Dann siehst du welcher Index das ist. Erlaubt sind ja nur 0 bis 6.

    Oder mach da noch ein assert . http://www.cplusplus.com/reference/cassert/assert/



  • Philipp2706 schrieb:

    Schlangenmensch schrieb:

    Was soll while(cin) bewirken? Warum springst du vor der while Überprüfung mit break aus der Schleife?

    Das break habe ich vergessen zu löschen, aber eigentlich funktioniert while (cin) doch. (Vorausgesetzt das Programm würde sich nicht beenden).

    Okay, ich stell die Frage mal anders: Weißt du auch warum das funktioniert?


Anmelden zum Antworten