C-Programm Tage zwischen zwei Datumsangaben
Ich habe ein Programm geschrieben, dass sollte finden die Tage zwischen zwei Daten, aber es hat einige Problemchen. Die Logik macht absolut Sinn in meinem Kopf, wenn ich Lesen es, also bin ich-vorausgesetzt ich habe einige syntax-Fehler, dass ich immer mit einem Blick über oder so etwas.
Erstens, bei der Eingabe von zwei Datumsangaben in verschiedenen Jahren, der Ausgang ist immer ausgeschaltet, indem über einen Monat (31 in den meisten Fällen, aber 32 in einem Fall...go figure). Zweite, zwei Termine genau einen Monat auseinander zurück, die Anzahl der Tage im zweiten Monat (z.B. 1/1/1 zu 2/1/1 Erträge 28). Gibt es zwangsläufig einige andere seltsame Dinge, dass dieses Programm funktioniert, aber ich hoffe, das ist genug Informationen, um Ihnen zu helfen Jungs herauszufinden, was ich falsch mache. Für das Leben von mir ich kann nicht herausfinden this one out auf meiner eigenen. Ich bin relativ neu in C, so bitte sanft sein =)
Dank
//Calculates the number of calendar days between any two dates in history (beginning with 1/1/1).
#include <stdio.h>
#include <stdlib.h>
void leap(int year1, int year2, int *leap1, int *leap2);
void date(int *month1, int *day1, int *year1, int *month2, int *day2, int *year2, int *leap1, int *leap2);
int main(void)
{
int month1, day1, year1, month2, day2, year2, leap1, leap2;
int daysPerMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int daysPerMonthLeap[] = {31,29,31,30,31,30,31,31,30,31,30,31};
leap(year1, year2, &leap1, &leap2);
date(&month1, &day1, &year1, &month2, &day2, &year2, &leap1, &leap2);
if(year1 == year2)
{
int i, total;
if(month1 == month2) //Total days if month1 == month2
{
total = day2 - day1;
printf("There are %d days between the two dates.", total);
}
else
{
if(leap1 == 1)
total = daysPerMonthLeap[month1] - day1;
else
total = daysPerMonth[month1] - day1;
for(i = month1 + 1; i < month2; i++) //Days remaining between dates (excluding last month)
{
if(leap1 == 1)
total += daysPerMonthLeap[i];
else
total += daysPerMonth[i];
}
total += day2; //Final sum of days between dates (including last month)
printf("There are %d days between the two dates.", total);
}
}
else //If year1 != year2 ...
{
int i, total, century1 = ((year1 / 100) + 1) * 100, falseleap = 0;
if(leap1 == 1)
total = daysPerMonthLeap[month1] - day1;
else
total = daysPerMonth[month1] - day1;
for(i = month1 + 1; i <= 12; i++) //Day remaining in first year
{
if(leap1 == 1)
total += daysPerMonthLeap[i];
else
total += daysPerMonth[i];
}
for(i = 1; i < month2; i++) //Days remaining in final year (excluding last month)
{
if(leap2 == 1)
total += daysPerMonthLeap[i];
else
total += daysPerMonth[i];
}
int leapcount1 = year1 / 4; //Leap years prior to and including first year
int leapcount2 = year2 / 4; //Leap years prior to and NOT including final year
if(year2 % 4 == 0)
leapcount2 -= 1;
int leaptotal = leapcount2 - leapcount1; //Leap years between dates
for(i = century1; i < year2; i += 100) //"False" leap years (divisible by 100 but not 400)
{
if((i % 400) != 0)
falseleap += 1;
}
total += 365 * (year2 - year1 - 1) + day2 + leaptotal - falseleap; //Final calculation
printf("There are %d days between the two dates.", total);
}
return 0;
}
void leap(int year1, int year2, int *leap1, int *leap2) //Determines if first and final years are leap years
{
if(year1 % 4 == 0)
{
if(year1 % 100 == 0)
{
if(year1 % 400 == 0)
*leap1 = 1;
else
*leap1 = 0;
}
else
*leap1 = 1;
}
else
*leap1 = 0;
if(year2 % 4 == 0)
{
if(year2 % 100 == 0)
{
if(year2 % 400 == 0)
*leap2 = 1;
else
*leap2 = 0;
}
else
*leap2 = 1;
}
else
*leap2 = 0;
}
void date(int *month1, int *day1, int *year1, int *month2, int *day2, int *year2, int *leap1, int *leap2)
{
for(;;) //Infinite loop (exited upon valid input)
{
int fail = 0;
printf("\nEnter first date: ");
scanf("%d/%d/%d", month1, day1, year1);
if(*month1 < 1 || *month1 > 12)
{
printf("Invalid entry for month.\n");
fail += 1;
}
if(*day1 < 1 || *day1 > 31)
{
printf("Invalid entry for day.\n");
fail += 1;
}
if(*year1 < 1)
{
printf("Invalid entry for year.\n");
fail += 1;
}
if(daysPerMonth[month1] == 30 && *day1 > 30)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
if(*month1 == 2)
{
if(*leap1 == 1 && *day1 > 29)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
else if(*day1 > 28)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
}
if(fail > 0)
continue;
else
break;
}
for(;;)
{
int fail = 0;
printf("\nEnter second date: ");
scanf("%d/%d/%d", month2, day2, year2);
if(*year1 == *year2)
{
if(*month1 > *month2)
{
printf("Invalid entry.\n");
fail += 1;
}
if(*month1 == *month2 && *day1 > *day2)
{
printf("Invalid entry.\n");
fail += 1;
}
}
if(*month2 < 1 || *month2 > 12)
{
printf("Invalid entry for month.\n");
fail += 1;
}
if(*day2 < 1 || *day2 > 31)
{
printf("Invalid entry for day.\n");
fail += 1;
}
if(*year2 < 1)
{
printf("Invalid entry for year.\n");
fail += 1;
}
if(daysPerMonth[month2] == 30 && *day2 > 30)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
if(*month2 == 2)
{
if(*leap2 == 1 && *day2 > 29)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
else if(*day2 > 28)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
}
if(fail > 0)
continue;
else
break;
}
}
wahrscheinlich, dies ist ein anständig genug lernen problem, obwohl...
Für month1 = 1, ist, dass der Januar oder Februar in Ihrem code (basierend auf der daysPerMonth array)? Ich denke, dies ist eines der Probleme in Ihrem code. Geben Sie den code voranstellen eines Elements = 0 in beiden arrays oder verringern von Monat 1 während Sie die Berechnungen.
Beachten Sie, dass Sie sollten wahrscheinlich schneiden Sie aus dem frühesten Datum, an 1752 oder vielleicht 1923, wenn Sie wollen, dass es gut für alle in Europa...
markieren Sie eine der Antworten, die als "Angenommen", wenn das Problem vollständig gelöst.
InformationsquelleAutor Andbrik | 2012-04-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zunächst, dass
leap
Funktion fühlt sich überaus kompliziert; Sie brauchen nichts zu tun, beide Daten in einen Funktionsaufruf, und ich bin mir sicher, dass geschrieben werden kann, mehr kurz und bündig, so dass es mehr als offensichtlich richtig. Hier eine version hab ich noch rumfliegen, der nicht prägnante, aber ich bin überzeugt es ist leicht zu überprüfen, die Logik:Man könnte es so nennen:
Keine Zeiger und deutlich weniger code-Duplizierung. Ja, ich weiß, dass
is_leap_year()
reduziert werden kann, um eine einzelneif(...)
Aussage, aber das ist einfach für mich zu Lesen.Zweite, ich glaube, du hast bekam ein Missverhältnis zwischen 0-indizierte arrays und 1-indiziert menschliche Monaten:
vs
Dritte, ich denke, dass die Tage pro Monat berechnet werden können, etwas schöner:
Hier, ich nehme an, der Januar ist 0; würden Sie brauchen, um zu erzwingen, den rest des Codes zu entsprechen. (Ich lernte diese Doppel-array-trick von Die Elemente der Programming-Stil (Seite 54).) Der beste Teil der mit einer routine wie diese ist, dass es entfernt die Sprung-Bedingung aus der Differenz Berechnung.
Vierten, du bist die Indizierung von arrays außerhalb Ihrer Grenzen:
Dies ist nur ein weiteres Beispiel des Problems mit 0-indizierte arrays und 1-indiziert Monate -- aber sicher sein, dass Sie fix diese, auch wenn Sie zu beheben, die Monate.
Ich habe Angst, dass ich Sie noch nicht gefunden haben, alle die Fragen -- Sie finden es möglicherweise einfacher, Art das erste und das zweite Datum nach Eingabe und entfernen Sie alle, die überprüfung von code-und dann die Namen zu verwenden, die
before
undafter
oder etwas zu geben-Namen, die leichter zu denken, in den komplizierten Kern der Berechnung.Vielen Dank für die Hilfe. Es stellt sich heraus, dass mein array-Indizierung war das einzige, was Durcheinander me up facepalm. Funktioniert Super jetzt!
obwohl array-index war das einzige problem, nehmen Sie sich sarnold Anregungen zu berücksichtigen, dass das Programm effizient und kurz.
Die
is_leap_year()
Funktion könnte reduziert werden auf eine einzigereturn
keineif
notwendig. 🙂 Nur den Hinweis, ich verstehe, dass es ist optimiert für die Lesbarkeit.Ha! Guter Punkt. 🙂
InformationsquelleAutor sarnold
Dies ist nicht eine vollständige Antwort. Ich wollte nur erwähnen, einen besseren Weg, um zu berechnen, Schaltjahr (aus
The C Programming Language
- Seite #41)InformationsquelleAutor Sangeeth Saravanaraj
Reduzieren alle Monat Indizes, die von 1.
Was ich damit sagen will ist Januar entsprechen
daysPerMonth[0]
oderdaysPerMonthLeap[0]
und nichtdaysPerMonth[1]
oderdaysPerMonthLeap[1]
.Der Grund für diese als array-Indizes beginnen bei 0.
Also, wo immer Sie sind mit
month1
,month2
innendaysPerMonth[]
oderdaysPerMonthLeap[]
verwendenmonth1-1
undmonth2-1
statt.Ich hoffe das ist klar genug.
Ansonsten, feel free to comment.
würdest du gerne deine endgültige code?
InformationsquelleAutor tumchaaditya
Ändern
zu
d.h. pad-arrays am Anfang, da alle der code basiert auf der array-Werte beginnen bei element 1 eher als element 0.
Wird, loszuwerden, die Fehler, die Sie klagte.
Das andere problem ist ein off-by-one-Fehler beim hinzufügen
day2
insgesamt. In beiden Fällen sollten Sieday2 - 1
eher alsday2
. Dies ist auch aufgrund der Datum-Indizes beginnen bei 1 statt bei 0.Nachdem ich diese änderungen vorgenommen hat (plus ein paar, nur um den code zu kompilieren), es funktioniert einwandfrei.
Das ist die
day2 - day1
Fall, wo die Tage sind im gleichen Monat. Die beiden Zuordnungen zu ändern, sind diejenigen, wo Tag2 Hinzugefügt wird, ohne day1 abgezogen.Danke, das gab mir Kopfschmerzen lol.
InformationsquelleAutor Kyle Jones
Gibt es mehrere Probleme in Ihrem code-snippet.. aber ich muss sagen, es ist ein sehr guter Versuch. Es gibt viele kurze Schnitte, um das, was Sie versuchen zu erreichen.
Ich geschrieben habe das folgende Programm, mit dem man die Anzahl der Tage zwischen zwei gegebenen Daten. Sie können verwenden Sie diese als Referenz.
Die Ausgabe ist wie folgt:
Hinweis: dies ist kein vollständiges Programm. Es fehlt input-Validierung.
Hoffe, es hilft!
InformationsquelleAutor Sangeeth Saravanaraj
InformationsquelleAutor Vinay Kaple