2012-04-25 14 views
6

मैंने एक प्रोग्राम लिखा है कि दो तिथियों के बीच के दिनों को ढूंढना चाहिए, लेकिन इसमें कुछ हिचकी हैं। जब मैं इसे पढ़ता हूं तो तर्क मेरे सिर में सही समझ में आता है, इसलिए मुझे लगता है कि मेरे पास कुछ वाक्यविन्यास त्रुटियां हैं जिन्हें मैं चमक रहा हूं या कुछ।सी दो दिनों के बीच कार्यक्रम दिन

सबसे पहले, अलग-अलग वर्षों में दो तिथियों में प्रवेश करते समय, उत्पादन लगभग एक महीने तक रहता है (ज्यादातर मामलों में 31, लेकिन एक मामले में 32 ... आंकड़े जाओ)। दूसरा, दो महीने ठीक दो महीने अलग-अलग महीने में दिनों की संख्या लौटाएंगे (यानी 1/1/1 से 2/1/1 उपज 28)। अनिवार्य रूप से कुछ अन्य अजीब चीजें हैं जो इस कार्यक्रम में करती हैं, लेकिन मुझे उम्मीद है कि यह जानने में आपकी मदद करने के लिए पर्याप्त जानकारी है कि मैं क्या गलत कर रहा हूं। मेरे जीवन के लिए मैं इसे अपने आप से नहीं समझ सकता। मैं अपेक्षाकृत सेल्सियस के लिए नया हूँ, इसलिए = कोमल हो कृपया)

धन्यवाद

// 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; 
     } 
} 
+0

इस के लिए कोई lib नहीं है? – mkoryak

+0

@mkoryak, शायद, यह एक सभ्य पर्याप्त सीखने की समस्या है हालांकि ... – sarnold

+0

महीने 1 = 1 के लिए, क्या वह जनवरी या फरवरी आपके कोड में है (दिनों के आधार पर पेरमोन्थ सरणी)? मुझे लगता है कि यह आपके कोड में से एक समस्या है। आप गणना करते समय कोड दोनों एरे में तत्व = 0 को प्रीपेड करते हैं या 1 से 1 महीने कम करते हैं। – spicavigo

उत्तर

3

द्वारा 1.

मैं क्या कह जनवरी daysPerMonth[0] या daysPerMonthLeap[0] और के अनुरूप नहीं है इसका मतलब यह सब माह अनुक्रमित कम daysPerMonth[1] या daysPerMonthLeap[1] नहीं। इस किया जा रहा सरणी अनुक्रमणिका के लिए कारण से 0.

तो, शुरू भी आप daysPerMonth[] या daysPerMonthLeap[] अंदर month1, month2 उपयोग कर रहे हैं, month1-1 और month2-1 बजाय का उपयोग करें।

मुझे आशा है कि यह पर्याप्त स्पष्ट है। अन्यथा, टिप्पणी करने के लिए स्वतंत्र महसूस करें।

+0

यूप, हाहा। इसे फिक्स्ड और यह खूबसूरती से काम करता है। = डी – Andbrik

+0

@ एंड्रिक, क्या आप अपना अंतिम कोड साझा करना चाहते हैं? – bob90937

6

सबसे पहले, leap फ़ंक्शन अत्यधिक जटिल महसूस करता है; आपको एक फ़ंक्शन कॉल में दोनों तिथियां करने की आवश्यकता नहीं है, और मुझे यकीन है कि अधिक संक्षेप में लिखा जा सकता है ताकि यह अधिक स्पष्ट रूप से सही हो। यहाँ एक संस्करण मुझे लगता है कि चारों ओर बिछाने गया हो जाता है संक्षिप्त नहीं है लेकिन मैं इसे तर्क देखना आसान है कि आश्वस्त हूं:

int is_leap_year(int year) { 
     if (year % 400 == 0) { 
       return 1; 
     } else if (year % 100 == 0) { 
       return 0; 
     } else if (year % 4 == 0) { 
       return 1; 
     } else { 
       return 0; 
     } 
} 

आप इस तरह यह कह सकते हैं:

int year1, year2, leap1, leap2; 
year1 = get_input(); 
year2 = get_input(); 
leap1 = is_leap_year(year1); 
leap2 = is_leap_year(year2); 

कोई पॉइंटर्स और काफी कम कोड डुप्लिकेशन। हां, मुझे पता है कि is_leap_year() को एक if(...) कथन में घटाया जा सकता है, लेकिन मेरे लिए यह पढ़ना आसान है।

दूसरा, मैं तुम्हें 0 अनुक्रमित सरणियों और 1 अनुक्रमित मानव महीने के बीच एक बेमेल मिल रहे हैं लगता है:

  if(*month1 < 1 || *month1 > 12) 

बनाम

int daysPerMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 

तीसरा, मुझे लगता है कि प्रति माह दिनों कर सकते हैं थोड़ी अच्छी गणना की जा सकती है:

int days_in_month(int month, int year) { 
     int leap = is_leap_year(year); 
     /*    J F M A M J J A S O N D */ 
     int days[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
          {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; 
     if (month < 0 || month > 11 || year < 1753) 
       return -1; 

     return days[leap][month]; 
} 

यहां, मुझे लगता है कि जनवरी 0 है; आपको शेष कोड को मिलान करने के लिए मजबूर होना होगा। (मैंने The Elements of Programming Style (page 54) से इस डबल-सरणी चाल को सीखा।) इस तरह के दिनचर्या का उपयोग करने का सबसे अच्छा हिस्सा यह है कि यह अंतर गणना से लीप की स्थिति को हटा देता है।

चौथा, आप अपनी सीमा के बाहर सरणियों का अनुक्रमण कर रहे हैं:

  for(i = month1 + 1; i <= 12; i++) 
      { 
       if(leap1 == 1) 
        total += daysPerMonthLeap[i]; 

यह 0 से इंडैक्स सरणियों और 1-अनुक्रमित महीनों के साथ समस्या का सिर्फ एक उदाहरण है - लेकिन यकीन है कि तुम इसे ठीक हो, भी, जब आप महीनों को ठीक करते हैं।

मैं एक डर है कि मैं अभी तक सभी मुद्दों पर नहीं मिला है है - आप इसे आसान करने के लिए तरह पहले और इनपुट के बाद दूसरी तारीख मिल सकता है और जो कुछ सत्यापन कोड को दूर - और फिर नाम before का उपयोग और after या कुछ ऐसे नाम देने के लिए जो गणना के जटिल कोर में सोचने में आसान हैं।

+0

नाइस स्टाइल संदर्भ - क्या आप अलग-अलग 'अगर' ब्लॉक से छुटकारा पाने की सलाह भी देंगे जहां वर्षों के बराबर हैं? सामान्य समाधान इस मामले को संभालना चाहिए – nvuono

+0

सहायता के लिए धन्यवाद। यह पता चला है कि मेरी सरणी इंडेक्सिंग एकमात्र चीज थी जो मुझे गड़बड़ कर रही थी * फेसपाल्म *। अब महान काम करता है! – Andbrik

+0

@Andbrik: हालांकि सरणी सूचकांक एकमात्र समस्या थी, अपने कार्यक्रम को कुशल और छोटा बनाने के लिए सरनाल्ड के सुझावों को ध्यान में रखें। – tumchaaditya

3

यह एक पूरा जवाब नहीं है।

if ((year % 4 == 0 && year % 100 != 0) || year % 400 ==0) 
    printf("%d is a leap year \n", year); 
else 
    printf("%d is not a leap year \n", year); 
2

बदलें

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}; 

int daysPerMonth[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; 
int daysPerMonthLeap[] = {0,31,29,31,30,31,30,31,31,30,31,30,31}; 

यानी पैड सरणियों के लिए - मैं सिर्फ लीप वर्ष की गणना के लिए (पृष्ठ # 41 इस The C Programming Language से लिया जाता है) एक बेहतर तरीका उल्लेखित करना चाहते थे शुरुआत में, क्योंकि सभी कोड सरणी मानों पर तत्व 1 के बजाय तत्व 1 पर शुरू करने के लिए निर्भर करता है।

इससे शिकायत की गई त्रुटि से छुटकारा पड़ेगा।

दूसरी समस्या एक बार एक त्रुटि है जब आप कुल day2 जोड़ते हैं। दोनों मामलों में आपको के बजाय day2 - 1 जोड़ना चाहिए। यह 0.

के बाद 1 से शुरू होने वाली तिथि इंडेक्स के कारण भी है। इन परिवर्तनों के बाद (साथ ही संकलन करने के लिए कोड प्राप्त करने के लिए एक जोड़े), यह ठीक से काम करता है।

+0

दिन 2 और दिन 2-1 चीज़ के बारे में: दिन 2-1 उन 2 तिथियों (दोनों को छोड़कर) के बीच दिन देगा। लेकिन, जब हम आमतौर पर 2 तिथियों के बीच के दिनों की गणना करते हैं, तो इसकी परंपरागत ईयर दिन शामिल होती है। उदा। 4 मई और 1 मई के बीच का अंतर 3 दिनों के रूप में लिया जाता है .. 2 दिन नहीं ... – tumchaaditya

+0

यह 'दिन 2-दिन 1' मामला है, जहां दिन एक ही महीने में हैं। बदलने के लिए दो असाइनमेंट वे हैं जहां दिन 2 को बिना किसी दिन घटाया जा रहा है। –

+0

धन्यवाद, यह मुझे सिरदर्द दे रहा था। – Andbrik

1

आपके कोड स्निपेट में कई समस्याएं हैं .. लेकिन मुझे कहना होगा कि यह एक बहुत अच्छा प्रयास है। आप जो हासिल करने की कोशिश कर रहे हैं उसमें बहुत कम कटौती हैं।

मैंने निम्नलिखित कार्यक्रम लिखा है जो दो दी गई तिथियों के बीच दिनों की संख्या पाता है। आप इसे संदर्भ के रूप में उपयोग कर सकते हैं।

#include <stdio.h> 
#include <stdlib.h> 

char *month[13] = {"None", "Jan", "Feb", "Mar", 
        "Apr", "May", "June", "July", 
        "Aug", "Sept", "Oct", 
        "Nov", "Dec"}; 

/* 
daysPerMonth[0] = non leap year 
daysPerMonth[1] = leap year 
*/ 
int daysPerMonth[2][13] = {{-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
          {-1, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; 

typedef struct _d { 
    int day;  /* 1 to 31 */ 
    int month;  /* 1 to 12 */ 
    int year;  /* any */ 
}dt; 

void print_dt(dt d) 
{ 
    printf("%d %s %d \n", d.day, month[d.month], d.year); 
    return; 
} 

int leap(int year) 
{ 
    return ((year % 4 == 0 && year % 100 != 0) || year % 400 ==0) ? 1 : 0; 
} 

int minus(dt d1, dt d2) 
{ 
    int d1_l = leap(d1.year), d2_l = leap(d2.year); 
    int y, m; 
    int total_days = 0; 

    for (y = d1.year; y >= d2.year ; y--) { 
     if (y == d1.year) { 
      for (m = d1.month ; m >= 1 ; m--) { 
       if (m == d1.month) total_days += d1.day; 
       else    total_days += daysPerMonth[leap(y)][m]; 
       // printf("%d - %5s - %d - %d \n", y, month[m], daysPerMonth[leap(y)][m], total_days); 
      } 
     } else if (y == d2.year) { 
      for (m = 12 ; m >= d2.month ; m--) { 
       if (m == d2.month) total_days += daysPerMonth[leap(y)][m] - d2.day; 
       else    total_days += daysPerMonth[leap(y)][m]; 
       // printf("%d - %5s - %d - %d \n", y, month[m], daysPerMonth[leap(y)][m], total_days); 
      } 
     } else { 
      for (m = 12 ; m >= 1 ; m--) { 
       total_days += daysPerMonth[leap(y)][m]; 
       // printf("%d - %5s - %d - %d \n", y, month[m], daysPerMonth[leap(y)][m], total_days); 
      } 
     } 

    } 

    return total_days; 
} 

int main(void) 
{ 
    /* 28 Oct 2018 */ 
    dt d2 = {28, 10, 2018}; 

    /* 30 June 2006 */ 
    dt d1 = {30, 6, 2006}; 

    int days; 

    int d1_pt = 0, d2_pt = 0; 

    if (d1.year > d2.year)  d1_pt += 100; 
    else      d2_pt += 100; 
    if (d1.month > d2.month) d1_pt += 10; 
    else      d2_pt += 10; 
    if (d1.day > d2.day)  d1_pt += 1; 
    else      d2_pt += 1; 

    days = (d1_pt > d2_pt) ? minus(d1, d2) : minus(d2, d1); 

    print_dt(d1); 
    print_dt(d2); 
    printf("number of days: %d \n", days); 

    return 0; 
} 

उत्पादन इस प्रकार है:

$ gcc dates.c 
$ ./a.out 
30 June 2006 
28 Oct 2018 
number of days: 4503 
$ 

नोट: यह एक पूरा कार्यक्रम नहीं है। इसमें इनपुट सत्यापन की कमी है।

उम्मीद है कि यह मदद करता है!

+0

आप अपने परिणामों को प्रमाणित करने के लिए http://www.timeanddate.com/date/duration.html का उपयोग कर सकते हैं। –

0
//Difference/Duration between two dates 
//No need to calculate leap year offset or anything 
// Author: Vinay Kaple 
# include <iostream> 
using namespace std; 
int main(int argc, char const *argv[]) 
{ 
    int days_add, days_sub, c_date, c_month, b_date, b_month, c_year, b_year; 
    cout<<"Current Date(dd mm yyyy): "; 
    cin>>c_date>>c_month>>c_year; 
    cout<<"Birth Date(dd mm yyyy): "; 
    cin>>b_date>>b_month>>b_year; 
    int offset_month[12] = {0,31,59,90,120,151,181,212,243,273,304,334}; 
    days_add = c_date + offset_month[c_month-1]; 
    days_sub = b_date + offset_month[b_month-1]; 
    int total_days = (c_year-b_year)*365.2422 + days_add - days_sub+1; 
    cout<<"Total days: "<<total_days<<"\n"; 
    int total_seconds = total_days*24*60*60; 
    cout<<"Total seconds: "<<total_seconds<<"\n"; 
    return 0; 
} 
+0

कृपया कोड चिपकाए जाने से कोड स्निपेट के बारे में कुछ जानकारी साझा करें। – gmuraleekrishna

संबंधित मुद्दे

 संबंधित मुद्दे