Domanda

Ho una domanda per quanto riguarda qsort.

Questo è un po 'strano, ma la mia funzione qsort non mi dà l'output corretto. La cosa strana è che alcune delle mie funzioni confrontare sono identici ai miei progetti passati, ma non mi danno l'ingresso corretto a tutti. Io non sono sicuro di come testarlo.

Ad esempio:

int comp_name_asc(const void *a, const void *b)
{
  const Rec *prec1 = (const Rec *) a;
  const Rec *prec2 = (const Rec *) b;
  return strcmp(prec1->name, prec2->name); 
}

int comp_name_desc(const void *a, const void *b)
{
  const Rec *prec1 = (const Rec *) a;
  const Rec *prec2 = (const Rec *) b;
  return strcmp(prec2->name, prec1->name);
}

La seconda funzione deve essere ordine discendente, ma il risultato è identico: è sempre in ordine ascendente. Ho controllato per assicurarsi che la funzione di destra viene inserito al momento giusto. Rec è un typedef per una struttura che ho fatto, che ha un char * parametro name.

Anche (modificato per evitare il troppo pieno):

int comp_size_asc(const void *a, const void *b)
{
  const Rec *prec1 = (const Rec *) a;
  const Rec *prec2 = (const Rec *) b;

  if (prec1->byteSize > prec2->byteSize)
    return 1;
  else if (prec1->byteSize < prec2->byteSize)
    return -1;
  else
    return 0;
}

Il risultato è del tutto strano, non ascendente o discendente (es: 500, 515, 100, 200 ...). byteSize è di tipo off_t ottenuto facendo:

char *path; // Build the path
struct stat sb;
if (lstat(path, &sb) == 0) {
  // Read sb.st_size

Sono davvero non sicuro di come eseguire il debug di questo. Tutto quello che so, è che viene immessa la funzione di confronto appropriata, e che alcune funzioni confrontare simili utilizzati al lavoro in passato.

Tutte le idee o come posso eseguire il debug di questo sarebbe il benvenuto. Grazie.

EDIT:

L'aggiunta la chiamata a qsort:

int index = 0;
Rec **array = (Rec **) malloc(sizeof(Rec *) * capacity);
// Adds element to the array...
qsort(array, index, sizeof(Rec *), comp_name_desc);

(Ogni volta che un elemento viene aggiunto alla matrice, indice viene incrementato.)

Grazie.

EDIT:

La soluzione è stata riportata qui sotto. Grazie!

Ho dovuto cambiare:

const Rec *prec1 = (const Rec *) a;

a

const Rec *prec1 = *(const Rec **) a;

a causa di come ho definito il mio array. Grazie!

È stato utile?

Soluzione

Si dispone di una vasta gamma di Rec, o meglio, un array di puntatori Rec? Mi sto chiedendo perché la funzione di confronto diventa come parametri puntatori nella matrice, non direttamente ai record.

Ecco una dimostrazione di entrambi i modi:

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

typedef struct Rec {
  char *name;
} Rec;

/*
 * The pointers a and b point directly into the array,
 * where the Records themselves are.
 */
static int
cmp_Rec_by_name(const void *a, const void *b) {
  const Rec *rec1 = (Rec *)a;
  const Rec *rec2 = (Rec *)b;
  return strcmp(rec1->name, rec2->name);
}

/*
 * The pointers point directly into the array, where
 * not the records but pointers to them are. So they
 * are a pointer to a pointer to a record.
 */
static int
cmp_Rec_ptr_by_name(const void *a, const void *b) {
  const Rec *rec1 = *(Rec **)a;
  const Rec *rec2 = *(Rec **)b;
  return strcmp(rec1->name, rec2->name);
}

static void
sort_Rec(void) {
  Rec record[3];

  record[0].name = strdup("hello");
  record[1].name = strdup("world");
  record[2].name = strdup("how are you");
  qsort(record, 3, sizeof (Rec), cmp_Rec_by_name);

  for (int i = 0; i < 3; i++)
    printf("%s\n", record[i].name);
}

static void
sort_Rec_ptr(void) {
  Rec *(record[3]);

  record[0] = malloc(sizeof (Rec));
  record[1] = malloc(sizeof (Rec));
  record[2] = malloc(sizeof (Rec));
  record[0]->name = strdup("hello");
  record[1]->name = strdup("world");
  record[2]->name = strdup("how are you");
  qsort(record, 3, sizeof (Rec *), cmp_Rec_ptr_by_name);

  for (int i = 0; i < 3; i++)
    printf("%s\n", record[i]->name);
}

int
main() {
  sort_Rec();
  sort_Rec_ptr();
  return 0;
}

Altri suggerimenti

Non si dovrebbe mai confrontare i numeri sottraendo l'uno dall'altro. Questo in genere portare a troppo pieno con i tipi firmati e non funzionerà affatto con i tipi senza segno. Il linguaggio generico per il confronto con i numeri risultato tri-state è il seguente

(a > b) - (a < b)

In caso contrario, le funzioni di confronto guardare bene, in modo che il problema deve essere nel modo in cui si chiama la funzione di ordinamento.

ascoltare ciò che il comportamento è, la sensazione potrebbe essere che i nomi non sono in realtà i nomi, se strcmp() hanno i due argomenti scambiati ed i risultati è ancora crescente. Un suggerimento potrebbe essere quello di stampare i nomi utilizzando printf, e anche, di ridurre i nomi di 2 o 3 (numero di record), per rendere più facile per eseguire il debug e controllo per il motivo per cui si comporta in quel modo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top