gpt4 book ai didi

c - 对 struct tm 的数组进行排序

转载 作者:行者123 更新时间:2023-12-01 12:20:02 24 4
gpt4 key购买 nike

我目前正在用 C 编写个人日记,我希望能够打印按日期排序的帖子。我可以使用 struct tm 提取日期,但我不知道如何对日期进行排序,以便最新的日期位于最前面。这是我在这里的全部功能:

void dateOrder() {
FILE *postfile = fopen("post.txt", "r");

int numofpost = getNumOfPost(postfile);
int dates[numofpost];

struct tm ptime;

char *elt = malloc(5 * sizeof(char));
char *dref = "Date";
char *href = "Heure";
char c = 'c';

char *pseudo = malloc(20 * sizeof(char));
int pseudolen = 0;

rewind(postfile);

while (!feof(postfile)) {

fscanf(postfile, "%s", elt);

if (strcmp(elt, dref) == 0) {
fseek(postfile, 3, SEEK_CUR);
fscanf(postfile, "%d/%d/%d", (int)&(ptime.tm_mday), (int)&(ptime.tm_mon), (int)&(ptime.tm_year));
}

if (strcmp(elt, href) == 0) {
fseek(postfile, 3, SEEK_CUR);
fscanf(postfile, "%d:%d", (int)&(ptime.tm_hour), (int)&(ptime.tm_min));
}

ptime.tm_year -= 1900;
ptime.tm_mon -= 1;
ptime.tm_sec = 0;
ptime.tm_isdst = -1;
int rep = mktime(&ptime);

if (rep != -1) {
dates[i++] = rep;
}
}

insertsort(dates, sizeof(dates)/sizeof(dates[0]));

for (int i = 0; i < numofpost; i++) {
c = 'c';
rewind(postfile);

while (!feof(postfile) && c != 24) {

fscanf(postfile, "%s", elt);

if (strcmp(elt, "Pseudo") == 0) {
fseek(postfile, 3, SEEK_CUR);
fscanf(postfile, "%s", pseudo);
pseudolen = strlen(pseudo);
}

if (strcmp(elt, dref) == 0) {

fseek(postfile, 3, SEEK_CUR);
fscanf(postfile, "%d/%d/%d", (int)&(ptime.tm_mday), (int)&(ptime.tm_mon), (int)&(ptime.tm_year));
}

if (strcmp(elt, href) == 0) {
fseek(postfile, 3, SEEK_CUR);
fscanf(postfile, "%d:%d", (int)&(ptime.tm_hour), (int)&(ptime.tm_min));
}

ptime.tm_year -= 1900;
ptime.tm_mon -= 1;
ptime.tm_sec = 0;
ptime.tm_isdst = -1;
int mkt = mktime(&ptime);

if (mkt == dates[i]) {
fseek(postfile, -39, SEEK_CUR);
fseek(postfile, -pseudolen, SEEK_CUR);

while (c != 24) {
c = fgetc(postfile);

if (c == 24)
continue;

printf("%c", c);
}
}
}
}

fclose(postfile);
}

这是 struct tm :

struct tm {
int tm_sec; /* seconds, range 0 to 59 */
int tm_min; /* minutes, range 0 to 59 */
int tm_hour; /* hours, range 0 to 23 */
int tm_mday; /* day of the month, range 1 to 31 */
int tm_mon; /* month, range 0 to 11 */
int tm_year; /* The number of years since 1900 */
int tm_wday; /* day of the week, range 0 to 6 */
int tm_yday; /* day in the year, range 0 to 365 */
int tm_isdst; /* daylight saving time */
};

最佳答案

您可以使用mktime()difftime() 编写比较函数,然后使用qsort() 对数组进行排序tm 结构。 qsort() 可以使用下面的比较函数 cmp_dates_descend() 对日期数组进行降序排序:

#include <stdlib.h>
#include <time.h>

#define NUM_DATES 10 /* for example */

int cmp_dates_descend(const void *d1, const void *d2);

int main(void)
{
/* ... */

struct tm arr_dates[NUM_DATES];

/* ... */

size_t num_dates = sizeof arr_dates / sizeof *arr_dates;

qsort(arr_dates, num_dates, sizeof *arr_dates, cmp_dates_descend);

/* ... */

return 0;
}

int cmp_dates_descend(const void *d1, const void *d2)
{
struct tm *date_1 = (struct tm *) d1;
struct tm *date_2 = (struct tm *) d2;

return double d = -difftime(mktime(date_1), mktime(date_2));
}

请注意,此方法可能会遇到较大日期差异的问题。由于 difftime() 返回一个 double(表示以秒为单位的时间差),返回值可能无法用 int 表示,它是qsort() 使用的比较函数返回的值。其中INT_MAX == 2147483647,典型的4字节int,超过68年的日期差异将导致double转换时溢出> 到 int,因此是未定义的行为。如果要处理如此大的日期差异,或许应该编写自定义排序函数。

编辑

@chqrlie 在评论中指出,此方法还可能导致对非常接近的日期(几分之一秒)进行错误比较,因为如果 difftime(mktime(date_1), mktime(date_2))的量级小于1,返回时将值转换为0,比较相等。为避免这种复杂情况,difftime() 的结果可以存储在 double 中并与 0 进行比较以确定返回值。这是比较函数的常用技巧;这也消除了之前日期差异较大的问题。这是一个改进的比较函数:

int cmp_dates_descend(const void *d1, const void *d2)
{
struct tm *date_1 = (struct tm *) d1;
struct tm *date_2 = (struct tm *) d2;

double d = difftime(mktime(date_1), mktime(date_2));

return (d < 0) - (d > 0);
}

编辑2

要保持数组不变,这是比较函数在获取指向数组元素的 const 指针时应该做的,我们可以复制 tm 结构比较函数并以较小的性能成本在副本上调用 mktime():

int cmp_dates_descend(const void *d1, const void *d2)
{
struct tm date_1 = *(const struct tm *)d1;
struct tm date_2 = *(const struct tm *)d2;

double d = difftime(mktime(&date_1), mktime(&date_2));

return (d < 0) - (d > 0);
}

关于c - 对 struct tm 的数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45099976/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com