2017-03-19 115 views
1

我的程序以(月日年)格式獲取日期列表。然後按照最近事件的時間順序對它進行排序。它應該將從90到99,然後從00到12的年份排序。例如,應該對這個列表進行排序。按時間順序排列日期列表?

01年1月1日

00年1月1日

99年2月28日

12年7月17日

12年9月10日

00年7月1日

6月30日90

06年8月25日

08年5月27日

03年10月1日

進入這個。

12年9月10日

12年7月17日

08年5月27日

06年8月25日

03年10月1日

01年1月1日

7月1日00

00年1月1日

99年2月28日

九零年六月三十零日

不過,我似乎無法得到排序才能正常工作。

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

/* constants for max chars, max day, max year, max size */ 
enum { MAXC = 12, MAX_DAY = 31, MAX_YEAR = 2017, MAX_SIZE = 1000 }; 

typedef struct { 
    char month[MAXC]; /* either make static or allocate separately */ 
    unsigned day; 
    unsigned year; 
} date; 

/* empty character remaining in stdin */ 
void empty_stdin() 
{ 
    int c; 
    while ((c = getchar()) != '\n' && c != EOF) {} 
} 

/* sort struct date on year */ 
int sort (const void *a, const void *b) 
{ 
    date *date1 = (date *) a; 
    date *date2 = (date *) b; 

    if (date2->year != date1->year) 
     return (date1->year < date2->year) - (date1->year > date2->year); 

    return (date1->year < date2->year) - (date1->year > date2->year); 




    return 0; 
} 

/* output n elements of array of struct date */ 
void output (date *ar, int n) 
{ 
    int i; 

    printf ("\nOutput sorted by year:\n\n"); 

    for (i = 0; i < n; i++) 
     printf (" %s %d %d\n", ar[i].month, ar[i].day, ar[i].year); 
} 

int main (void) { 

    int i, n; 
    date *ar = NULL; 

    while (1) {  /* obtain valid 'n', compare with using fgets below */ 

     int rtn; /* varaible to save return of scanf -- always validate */ 

     //printf ("Enter number of dates to be entered (between 1 & 1000): "); 
     if ((rtn = scanf ("%d", &n)) != 1) { /* if conversion failed */ 
      if (rtn == EOF) { /* test for user cancelation of input */ 
       fprintf (stderr, "note: user canceled input, exiting.\n"); 
       return 0; 
      }     /* otherwise simply an invalid input */ 
      fprintf (stderr, "error: invalid input.\n"); 
      goto tryagain; 
     } 

     if (n < 0) {   /* invalid input < 0 */ 
      fprintf (stderr, "error: invalid input (n < 0).\n"); 
      goto tryagain; 
     } 

     if (n > MAX_SIZE) {  /* invalid input > MAX_SIZE */ 
      fprintf (stderr, "error: invalid input (n > %d).\n", MAX_SIZE); 
      goto tryagain; 
     } 

     break;  /* if we are here - we have a good value, break */ 

     tryagain:; /* label for goto to jump over break */ 

     empty_stdin(); /* empty characters that remain in input buffer */ 
    } 

    empty_stdin();  /* empty characters that remain in input buffer */ 

    /* allocate array of struct ar, n elements */ 
    if ((ar = malloc (sizeof *ar * n)) == NULL) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; 
    } 

    /* provide format instructions */ 
    //printf ("Enter the date month day year\n" 
      // " format, e.g.: Jan 18 2017\n\n"); 

    for (i = 0; i < n;) { /* loop until all elements filled */ 

     char buf[MAX_DAY + 1] = "", ans[MAXC] = ""; 

     //printf (" date[%2d] : ", i + 1); /* prompt for input */ 

     /* if fgets return is NULL, EOF encountered */ 
     if (fgets (buf, MAX_DAY + 1, stdin) == NULL) { 
      fprintf (stderr, "note: user canceled input, exiting.\n"); 
      return 0; 
     } 

     if (*buf == '\n') { /* if first char is '\n', user just hit enter */ 
      printf ("no input provided, quit (y/n)? "); 
      if (fgets (ans, MAXC, stdin) && (*ans == 'y' || *ans == 'Y')) 
       return 0; 
      else if (!*ans) { /* if ans NULL, EOF encountered */ 
       fprintf (stderr, "note: user canceled input, exiting.\n"); 
       return 0; 
      } 
     } 

     /* parse with sscanf, validate 3 conversion took place */ 
     if (sscanf (buf, "%11s %u %u", ar[i].month, &ar[i].day, &ar[i].year) != 3) 
     { 
      fprintf (stderr, "error: invalid input.\n"); 
      continue; 
     } 

     i++; /* only increment if valid sscanf conversion took place */ 
    } 

    qsort (ar, n, sizeof (date), sort);  /* sort by year */ 

    output (ar, n);  /* output results */ 

    free (ar);  /* free ar - you allocate it, you free it */ 

    return 0; 
} 
+1

4> 3明顯(如04> 03),但99> 4也是,對嗎?如果您希望事情的排序方式與正常情況不同,則需要指定要控制的排序標準。 –

+0

好吧,我希望它在這個標準在最近的日期與這個標準排序,比較年份從00到12,並按時間順序排序,然後比較90年至99年和排序。我不知道如何排序,因爲我不能用最大的整數對它進行排序。我已經試圖排序,如果它在同一年 – M33tM03

回答

-1

像計時狐狸說你的日期是大概是1900年的比你的日期是在2000年代似乎更大,以您的sort功能。

例如Jan 01 1999似乎大於Jan 01 2017,因爲Jan 01 99和Jan 01 17

最簡單的解決方法是告訴用戶輸入(並且只接受)整年,而不僅僅是最後兩位數字。 (根據OP的評論)

編輯:

測試,如果年是90和99或00和12之間然後相應地添加。

這基本上只是rici回答的更詳細的版本。

... 
/* parse with sscanf, validate 3 conversion took place */ 
if (sscanf (buf, "%11s %u %u", ar[i].month, &ar[i].day, &ar[i].year) != 3) 
{ 
    fprintf (stderr, "error: invalid input.\n"); 
    continue; 
} 
else 
{ 
    // add 1900 if the year is 90 or greater 
    if(ar[i].year >= 90) 
    ar[i].year += 1900; 

    // add 2000 if the year is 12 or less 
    else if(ar[i].year <= 12) 
    ar[i].year += 2000; 
} 
... 
+0

那麼需求是我排序的最後兩位數字,如果它排序一整年的日期,那麼我不會有任何麻煩。 – M33tM03

+0

我對此感到困惑。如果輸入無效,爲什麼要添加1900或2000?如果一年未成功分配,那麼您將1900或2000添加到未初始化的值...? –

+0

我完全搞砸了......現在修好了...... –

1

最簡單的解決辦法可能是你在閱讀後,固定年(然後將其放回當你打印出來,如果需要的話,2000年易發代碼)。

unsigned yy; 
... sscanf (buf, "%11s %u %u", ar[i].month, &ar[i].day, &yy) ... 
ar[i].year = yy >= 90 ? 1900 + yy : 2000 + yy 

你必須調整90爲您打算使用的實際截止。

您可以類似地將月份轉換爲整數。或者你甚至可以把輸入翻譯成像朱利安一樣的東西,從而使得排序變得微不足道,但輸出稍微複雜一些。如果你有很多日期需要排序,簡化排序是一個勝利。

+0

我在執行你的想法到我的代碼時遇到了麻煩,你能詳細說明一下嗎? – M33tM03