如何从C中的数组排序日期

时间:2018-11-05 17:38:42

标签: c

我正在尝试对数组中的日期进行排序,我得到了以下代码(不包括我要读取的数组和文件,以及其他我要写入的排序日期。

int aniomayor=tot[0].anio;
int diamayor=tot[0].dia;
int mesmayor=tot[0].mes;

while (i<nf) {
  if (tot[i].anio > aniomayor) {
    int aniomayor=tot[i].anio;
    int diamayor=tot[i].dia;
    int mesmayor=tot[i].mes;
  }
  else if (tot[i].anio == aniomayor && tot[i].mes > mesmayor) {
    int aniomayor=tot[i].anio;
    int diamayor=tot[i].dia;
    int mesmayor=tot[i].mes;
  }
  else if (tot[i].anio == aniomayor && tot[i].mes == mesmayor &&  tot[i].dia > diamayor) {
    int aniomayor=tot[i].anio;
    int diamayor=tot[i].dia;
    int mesmayor=tot[i].mes;
  }

  i++;
}

fprintf(f, "%s ", diamayor);
fprintf(f, "%s ", mesmayor);
fprintf(f, "%s \n", aniomayor);

我认为它可以工作,但是在2,3,4 ..行中,它将始终打印相同的日期,我不知道如何忽略它已经排序的日期。预先感谢。

2 个答案:

答案 0 :(得分:5)

原始int声明建立变量。后续的变量将创建名称相同但不相同的“影子”变量。

这是一个示范:

#include <stdio.h>

int main() {
  int x = 1;

  if (x == 1) {
    int x = 2;
    printf("x=%d\n", x);
  }

  printf("x=%d\n", x);

  return 0;
}

此打印:

x=2
x=1

顶级x从未被修改,因此它似乎恢复为原始值。

您应该从其中删除int前缀,只需将其分配给现有变量即可。

当您在C语言中说int x = y;时,您是在声明一个变量并分配一个值。分配给现有变量x = y;就足够了。

int前缀仅在变量的第一个实例上是必需的,因此编译器知道用于该类型的类型以及所有在同一范围内的所有后续引用。

现在,通常编译器会抱怨如果在相同范围内完成另一个具有相同名称的变量。就您而言,因为您是在if内进行操作,从技术上讲,这是一个不同的范围,因此您可以重复。

答案 1 :(得分:0)

正如注释中提到的,最好使用qsort,(如果不关心稳定性的话)。需要一个函数指针,在下面的代码中为compare_dates

#include <stdlib.h> /* EXIT*, rand, qsort */
#include <stdio.h>  /* *printf */
#include <time.h>   /* clock */
#include <assert.h> /* assert */

struct Date { int anio, mes, dia; };

/** Random [i, j]. https://stackoverflow.com/a/6852396/2472827
 This is just used for test purposes. */
static int rand_range(const int i, const int j) {
    const unsigned long max = (unsigned long)j - i,
        num_bins = max + 1l,
        num_rand = (unsigned long)RAND_MAX + 1,
        bin_size = num_rand / num_bins,
        defect   = num_rand % num_bins;
    unsigned long x;
    assert(i <= j && num_bins <= RAND_MAX);
    do { x = 1l * rand(); } while (num_rand - defect <= x);
    return i + x / bin_size;
}

/** Initiaises the date with random. */
static void init_date(struct Date *const date) {
    assert(date);
    date->anio = rand_range(1950, 2050);
    date->mes  = rand_range(1, 12);
    date->dia  = rand_range(1, 30); /* Approximately. */
}

/** Prints the date in a static string.
 Assumes the date is sanitised, or else this presents a risk of overflow. */
static const char *print_date(const struct Date *const date) {
    static char print[128]; /* Should be 11 if -999 <= year < 9999. */
    assert(date);
    sprintf(print, "%4.4d-%2.2d-%2.2d", date->anio, date->mes, date->dia);
    return print;
}

/** The arguments must be const struct Date *.
 @return -, =, + */
static int compare_dates(const void *p, const void *q) {
    const struct Date *x = (const struct Date *)p, *y = (const struct Date *)q;
    assert(p && q);
    if(x->anio > y->anio) return 1;
    if(x->anio < y->anio) return -1;
    if(x->mes  > y->mes)  return 1;
    if(x->mes  < y->mes)  return -1;
    if(x->dia  > y->dia)  return 1;
    if(x->dia  < y->dia)  return -1;
    return 0;
}

int main(void) {
    struct Date dates[64];
    const size_t dates_size = sizeof dates / sizeof *dates;
    size_t i;

    /* Generate dates. */
    srand((unsigned)clock());
    for(i = 0; i < dates_size; i++) init_date(dates + i);
    /* Sort it using compare_dates. */
    qsort(dates, dates_size, sizeof *dates, &compare_dates);
    /* Print. */
    for(i = 0; i < dates_size; i++) printf("%s.\n", print_date(dates + i));

    return EXIT_SUCCESS;
}

请参见How to generate a random integer number from within a range