2017-03-19 34 views
0

我試圖使一個程序,用一年是一年中的最後兩位數字的排序(年月日的格式日期的列表。我的計劃應該多年來日期排序在90到99,然後從00到12.I不能得到正常的排序無法排序與結構日期

因此,例如,如果輸入的是這樣的:

01年1月1日

90年6月30日

01年10月1日

它應該把它整理到

01年10月1日

01年1月1日

九零年六月三十○日

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

/* constants for max chars, max day, max year, max size */ 
enum { MAXC = 12, MAX_DAY = 31, MAX_YEAR = 12, 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 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

它降低到[MCVE]。這對我們來說不是無關緊要的部分。你可能會一路發現問題。 – StoryTeller

+1

做'if(ar [i] .year <= MAX_YEAR)ar [i] .year + = 2000; else ar [i] .year + = 1900;'輸入'ar [i] .year'後。 ...'printf(「....%u \ n」,....,ar [i] .year%100);'在'output'排序後。 – BLUEPIXY

+1

以前的評論:'%u' - >'%02u'。 – BLUEPIXY

回答

2

你可能明白這一點:

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

不作任何任何意義。

這裏是你想要的東西:

int year1 = fix_year(date1->year); 
int year2 = fix_year(date2->year); 
return year1 - year2; 

其中fix_year()如下:

int fix_year(int year) 
{ 
    return (year >= 90? 2000 : 1900) + year; 
} 

這是說

int fix_year(int year) 
{ 
    if(year >= 90) 
     return 1900 + year; 
    return 2000 + year; 
} 

注意的另一種方式,以後你也會必須擺脫char month[MAXC];成員並將其替換爲int month;,因爲在英語月份的名稱的詞典順序(在地球上任何語言,我願意猜)絕對沒有關係的幾個月的編號。

+0

非常感謝您的幫助!這個問題在過去的4個小時裏讓我瘋狂。現在我需要問的是,是否有任何方法可以翻轉輸出的順序,以便從最近的日期到最早的日期而不是其他方式? – LookingWest

+1

嗯,當然,只是'回到year2 - year1';' –

+0

哦,我已經假設在評論你已經知道'return year2 - year1'不起作用,至少在我用在我的例子中題。這就是爲什麼我問,因爲我不明白爲什麼它不會像它應該那樣翻轉輸出。 – LookingWest