我如何在 c 中订购日期结构?

Posted

技术标签:

【中文标题】我如何在 c 中订购日期结构?【英文标题】:how can i order a date struct in c? 【发布时间】:2022-01-07 02:59:40 【问题描述】:

我有这个程序,我有一个结构,我必须从 file.txt 中保存一些日期(日-月-年)。 之后,我必须对其进行一些控制,例如可视化,按特定顺序可视化,ecc ... 我试图以升序可视化结构,因此从“最低”日期到“最高”日期。 我正在使用 qsort 函数,但是当我使用它时,它只是排序日期,而不是月份和年份。

我该如何解决这个问题? 我把代码放在这里。

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

struct date            //<-- struct for the dates
    int giorno;
    int mese;
    int anno;
;

struct date *leggi_file(FILE *fp, int *size)       //<-- im reading the file and saving the text in the struct
    int dim = 16;
    struct date *d;
    if(!(d = malloc(dim *sizeof(struct date))))
        free(d);
        return NULL;
    
    char buf[60];
    while(fgets(buf, sizeof(buf), fp) != NULL)
        if(3 != sscanf(buf, "%d/%d/%d", &d[*size].giorno, &d[*size].mese, &d[*size].anno))
            puts("data incompleta");
            continue;
        
    (*size) = (*size) +1;
        if(dim >= (*size))
            dim *= 2;
            if(!(d = realloc (d, dim * sizeof(struct date))))
                return 0;
        
    
    d = realloc(d,(*size) * sizeof(struct date));
    return d;


void stampafile(struct date *d, int size)      //<-- im printing on screen the file
    int i;

    for(i=0; i<size; i++)
        printf("%d giorno %d mese %d anno\n", d[i].giorno, d[i].mese, d[i].anno);
    


int cmpfunc(const void *a, const void *b)
    return (*(int*)a - *(int*)b);


void ordinadate(struct date *d, int size)
    int i;
    qsort(d, size, sizeof(*d), cmpfunc);
    printf("\nqsort giorni\n");

    for(i=0; i<size; i++)
        printf("%d %d %d\n", d[i].giorno, d[i].mese, d[i].anno);
    


int main(int argc, char *argv[])
    struct date *d;
    FILE *fp;
    fp = fopen(argv[1],"r");
    int size= 0;

    if(fp == 0)
        return 1;
    
    
    if(!(d = leggi_file(fp, &size)))
        return 0;
    

    stampafile(d, size);
    ordinadate(d, size);        //function orderdate
    fclose(fp);
    free(d);


txt文件是这样的:

10/12/2012
10/11/2011
07/06/2001
...

【问题讨论】:

return (*(int*)a - *(int*)b); 不知道为什么你认为转换为错误的类型是个好主意。将其转换为正确的struct date * 并编写逻辑来比较年、月和日。 【参考方案1】:

这样做:

int cmpfunc(const void *a, const void *b)
    return (*(int*)a - *(int*)b);

您只比较struct 的第一个成员:giorno

您需要比较所有成员:

int cmpfunc(const void *a, const void *b)
    const struct date *pa = a;
    const struct date *pb = b;

    int anno = pa->anno - pb->anno;
    int mese = pa->mese - pb->mese;
    int giorno = pa->giorno - pb->giorno;

    return anno != 0 ? anno :
           mese != 0 ? mese :
           giorno;

【讨论】:

或者,不那么紧凑但可能更明显:if(pa-&gt;anno &lt; pb-&gt;anno) return -1; else if(pa-&gt;anno &gt; pb-&gt;anno) return +1; else if(pa-&gt; mese &lt; pb-&gt; mese) return -1; else if(pa-&gt; mese &gt; pb-&gt; mese) return +1; else if(pa-&gt; giorno &lt; pb-&gt; giorno) return -1; else if(pa-&gt; giorno &gt; pb-&gt; giorno) return +1; else return 0;(嗯,正确缩进时更明显,也就是说。:-)) @SteveSummit 是的,很好,我使用这种格式来保留 OPs 方法:(*(int*)a - *(int*)b) 或两者兼而有之,例如:int delta = pa-&gt;anno - pb-&gt;anno; if (!delta) delta = pb-&gt;mese - pb-&gt;mese; if (!delta) delta = pa-&gt;giorno - pb-&gt;giorno; return delta; 这也可以节省一些计算和变量 :-) 顺便说一句,我不知道我刚刚写了什么,我只是希望它的意思是“年"、"月" 和 "日" ;-) 或转换为“十进制”日期格式(如今天的数字 20211202)以消除 if-statements:return (pa-&gt;anno * 10000 + pa-&gt;mese * 100 + pa-&gt;giorno) - (pb-&gt;anno * 10000 + pb-&gt;mese * 100 + pb-&gt;giorno);

以上是关于我如何在 c 中订购日期结构?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中从 Firestore 订购数据,orderBy 订购不正确

当您有列名“日期”时如何订购表 desc?

如何在 GROUP BY 之前订购此数据库 [重复]

如何在 SqlAlchemy 上订购嵌套的 SQL SELECT

如何使用firebase通过查询进行订购[重复]

按日期订购事件