Fehlermeldung (Debug Assertion Failed)



  • Guten Abend,

    ich versuche gerade eine Funktion zur Datumsüberprüfung zu erstellen. Beim ersten Testversuchen erhalte ich die Fehlermeldung:
    (Debug Assertion Failed c>= -1 &&c<=255) wenn ich z.B. 20f bei c eingebe.
    Wie kann ich das nun abändern?

    int korrekt(char *tag, char*mon, char *jahr)
    {
    	char cht = tag;
    	char chm = mon;
    	char chj = jahr;
    	int a, b, c, e;
    	a = atoi(tag);
    	b = atoi(mon);
    	c = atoi(jahr);
    
    	if (c % 4 == 0)
    	{
    		if (c % 100 == 0)
    		{
    			if (c % 400 == 0)
    				e = 1;
    		}
    	}
    
    	else e = 0;
    
    	while ((cht = *tag++) != '\0') {
    		while ((chm = *mon++) != '\0') {
    			while ((chj = *mon++) != '\0') {
    				if (!isdigit(cht) || (!isdigit(chm) || (!isdigit(chj)) || ((b > 12) || (b < 1) || (a <= 0) || (a>31)))) {
    					return 0;
    					if (a <= 28) {
    						return 1;
    						if ((a == 29) && (b != 2))
    							return 1;
    						else if (e == 1)
    							return 1;
    						else return 0;
    						if ((a == 30) && (b != 2)) {
    							return 1;
    							if ((a == 31) && (b == 1) || (b == 3) || (b == 5) || (b == 7) || (b == 8) || (b == 10) || (b == 12)) {
    								return 1;
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    
    }
    

  • Mod

    Was gibst du wo ein?

    Dein Programm ist total wirr. Erst wandelst du Zeichenketten mit atoi in Zahlen um, behandelst das Ergebnis aber wie Buchstaben. Und dann machst du das gleiche noch einmal von Hand? 😕 Hast du einfach nur verschiedene Codes aus dem Internet zusammen kopiert?



  • - die Initialisierungen Zeile 3-5 sind Schrott
    - in Zeile 24 soll es ja wohl *jahr++ heißen
    - isdigit und Konsorten immer mit explizitem (unsigned char) Cast aufrufen



  • ja statt *mon hätte *jahr stehen müssen
    Wenn ich nun 29.2.2016 eingebe erhalte ich dieselbe Fehlermeldung wie oben beschrieben.

    Ich habe nichts kopiert, sondern so versucht aufzuschreiben wie es mir jemand gesagt hat.

    Habt ihr eine Idee wie man das Datum ordnungsgemäß einlesen könnte?



  • Trenne einlesen vom überprüfen.
    Einlesen geht z.B. mit scanf

    Du kannst ein 2D-Array machen, in dem die Anzahl der Tage in einem Monat steht

    int TageImMonat[2][12] = { {31,28,31,...31},
                               {31,29,......31} };
    

    Welchen Wert hat e für das Jahr 1900?

    Und nimm vernünftige Variablennamen.



  • Wie so oft gilt auch hier:
    Schreibe dir eine/mehrere Funktion, die Teilaufgaben abdecken und verwende die Standardbibliothek:

    time_t testDatum(const char*d)
    {
    	struct tm t={0};
    	unsigned a,b,c;
    	int n;
    	if( 3!=sscanf(d,"%u.%u.%4u%n",&a,&b,&c,&n) || d[n]) return -1;
    	t.tm_year = c-1900;
    	t.tm_mon = b-1;
    	t.tm_mday = a;
    	return mktime(&t)!=(time_t)-1?t.tm_year==c-1900&&t.tm_mon==b-1&&t.tm_mday==a?mktime(&t):-1:-1;
    }
    
    int main(void) {
    	time_t t;
    	puts((t=testDatum("1.1.1970"))==(time_t)-1?"?":ctime(&t));
    	puts((t=testDatum("29.2.2016"))==(time_t)-1?"?":ctime(&t));
    	puts((t=testDatum("29.2.2015"))==(time_t)-1?"?":ctime(&t));
    	puts((t=testDatum("1.1.1970abc"))==(time_t)-1?"?":ctime(&t));
    	puts((t=testDatum("1.1.197"))==(time_t)-1?"?":ctime(&t));
    	puts((t=testDatum("31.4.1970"))==(time_t)-1?"?":ctime(&t));
    	puts((t=testDatum("31.5.1970"))==(time_t)-1?"?":ctime(&t));
    	return 0;
    }
    

    http://ideone.com/FCkC02



  • Einem char (und auch allem anderen) kannst du aber keine Adresse zuweisen. Das wird wohl der Fehler sein, sofern der Rest denn funktioniert


  • Mod

    HansKlaus schrieb:

    Einem char (und auch allem anderen) kannst du aber keine Adresse zuweisen. Das wird wohl der Fehler sein, sofern der Rest denn funktioniert

    Kann man schon, sollte man nur nicht, da zu 99.999999% Unsinn. Derzeit ist der ganze Code voller Fehler dieser Art.



  • Wutz schrieb:

    time_t testDatum(const char*d)
    {
    	struct tm t={0};
    	unsigned a,b,c;
    	int n;
    	if( 3!=sscanf(d,"%u.%u.%4u%n",&a,&b,&c,&n) || d[n]) return -1;
    	t.tm_year = c-1900;
    	t.tm_mon = b-1;
    	t.tm_mday = a;
    	return mktime(&t)!=(time_t)-1?t.tm_year==c-1900&&t.tm_mon==b-1&&t.tm_mday==a?mktime(&t):-1:-1;
    }
    

    Wutz, magst du das return kurz erläutern?
    Weshalb zweimal mktime? So wie ich es lese, prüfst du ob es erfolgreich war, und wenn ja, dann prüfst du die Elemente nochmals einzeln und rufst bei Gleichheit nochmal mktime auf?



  • Es ist immer sehr hilfreich sich über die genaue Spezifikation der verwendeten Funktionen im Klaren zu sein, in diesem Fall mktime.
    mktime interpretiert eine struct tm und liefert ein time_t.
    Dabei ändert sie aber (u.U.) struct tm so ab, wie die Funktion es für richtig hält, z.B. bei 30.02.JJJJ wird struct tm in 2.3.JJJJ abgeändert; ob solche Änderung vorliegt wird einfach geprüft und wenn sie vorkam, wird fehlerhaft rückgegeben.
    Das 2. mktime spart einfach nur eine temp. Variable vom Typ time_t ein.


Anmelden zum Antworten