qsort массива структур не работает

Я пытаюсь отсортировать массив запуска структуры, называемый результатами, по символу, но когда я печатаю массив, ничего не сортируется. Посмотри на это:

struct run {
  char name[20], weekday[4], month[10];
  (And some more...)
};
typedef struct run run;

int name_compare(const void *a, const void *b) 
{
    run *run1 = *(run **)a;
    run *run2 = *(run **)b;
    return strcmp(run1->name, run2->name);
}

int count_number_of_different_persons(run results[])
{
  int i = 0;


  qsort(results, sizeof(results) / sizeof(run), sizeof(run), name_compare);

  for(i = 0; i <= 999; i++)
  {
    printf("%s\n", results[i].name);
  }
  // not done with this function yet, just return 0
  return 0;
}

Результатом вышеизложенного является просто список имен в том порядке, в котором они были изначально размещены.


person Andreas Strandfelt    schedule 02.12.2011    source источник


Ответы (3)


int count_number_of_different_persons(run results[])

На самом деле это не позволяет вам использовать sizeof в массиве, потому что массив распадается на указатель.

Этот

run *run1 = *(run **)a;

тоже выглядит странно, не так ли

run *run1 = (run*)a;

?

person Michael Krelin - hacker    schedule 02.12.2011
comment
void* a и void* b — указатели на элементы массива. Если сам массив состоит из указателей на структуру, имеющую typedef как run, то правильное приведение void* a будет (run**)a. Это по-прежнему просто указатель на указатель, поэтому, чтобы получить указатель на структуру, этот указатель-указатель необходимо разыменовать. Следовательно, *(run**)a. Хотя здесь это выглядит так, массив представляет собой не массив указателей, а прямой массив, что делает правильное приведение, как вы утверждаете, (run*)a. (Я столкнулся с этой проблемой только сейчас, нашел этот пост, подумал, что это поможет кому-то еще). - person Nick Bauer; 13.09.2015
comment
@NickBauer, я очень надеюсь, что это поможет кому-то еще, но я не могу расшифровать его сейчас, 4 года спустя, вне контекста и слишком ленив, чтобы перечитывать и переосмысливать исходный вопрос и ответ. - person Michael Krelin - hacker; 14.09.2015

Одна проблема в name_compare. Попробуйте это вместо этого:

int name_compare(const void *a, const void *b) 
{
    run *run1 = (run *)a;
    run *run2 = (run *)b;
    return strcmp(run1->name, run2->name);
}
person Klas Lindbäck    schedule 02.12.2011

Проверьте следующий код:

Как упоминал @michel, sizeof(array) предоставляет размер указателя, а не размер самого массива, так как при передаче массива он рассматривается как указатель. Следовательно, либо отправьте количество элементов в функцию count_number_of_ Different_persons, либо определите MACRO количества элементов. Надеюсь это поможет. :).

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

#define NOE 3

struct run
{
    char name[20];
};

typedef struct run run;

int name_compare (const void *a, const void *b )
{
    return strcmp (((run *)a)->name, ((run *)b)->name);
}

int count_number_of_different_persons(run results[], int noOfElements)
{
    int i=0;
    qsort(results, noOfElements, sizeof (run), name_compare);
    for (i=0; i<noOfElements; i++)
        printf ("%s\n",results[i].name);
}

int main ( int argc, char * argv[])
{
    run a, b, c;
    run  arg[NOE];

    strcpy (a.name, "love");
    strcpy (b.name, "you");
    strcpy (c.name, "i");
    arg[0] = a;
    arg[1] = b;
    arg[2] = c;

    count_number_of_different_persons(arg, sizeof(arg)/sizeof(run));
};
person Whoami    schedule 02.12.2011