Reputation: 9
I have these structs,
typedef struct
{
char *str; //register to store each element (one string)
} v_elemento;
/**
* this register has an array of elements, a counter for the size and another for the capacity
*/
typedef struct
{
/** numero de elementos do vetor */
int tamanho; //size
/** capacidade do vetor */
int capacidade; //capacity
/** array of stored elements */
v_elemento* elementos;
} vetor;
I heard that there is a qsort() function that allows me to sort an array, I tried checking the internet but all examples either use int, float or strings. How can I use the qsort() function using the structures above?
I want something like this
for(int i=0; i<vetor->tamanho;i++)
//sorts vetor->elemento[i].str
This is my cmp function;
int compara(v_elemento *p0,v_elemento *p1){
return strcmp(p0->str,p1->str);
}
This is my qsort() function:
qsort(vec->elementos,vec->tamanho, sizeof(v_elemento),compara)
Im gonna show you a code, which is working properly, it sorts what I want but it's selection sort:
int vetor_ordena_sel(vetor* vec)
{
//special cases
if(vec==NULL)
return -1;
if(vec->tamanho<=1) // already sorted
return 0;
// special cases
int i, j, posicao; //posicao is position
char *min_tmp;
for(i=0;i<(vec->tamanho);i++){
posicao=i;
for(j=i+1;j<(vec->tamanho);j++){
if(strcmp(vec->elementos[j].str,vec->elementos[posicao].str)<0)
posicao=j;
}
if(posicao!=i){
min_tmp=vec->elementos[i].str;
vec->elementos[i].str=vec->elementos[posicao].str;
vec->elementos[posicao].str=min_tmp;
}
}
return 0;
}
Am I doing something wrong?
Upvotes: 0
Views: 89
Reputation: 294
When writing comparison function for builtin sort functions, the pass in parameter should really be const void *
instead of any other type. Please refer to documentation.
I don't know the difference between "capacity" and "size" in that struct, but as you use the size variable in qsort, I'll do the same.
The following comparator works under gcc 4.2.1.
int compara(const void *p0, const void *p1)
{
return strcmp(((v_elemento *)p0)->str, ((v_elemento *)p1)->str);
}
As I said above, you should only pass in const void *
, so I made a type casting.
Below is the driver code I wrote:
// Test case.
vetor *vec = malloc(sizeof(vetor));
vec->tamanho = 5;
vec->elementos = malloc(5 * sizeof(v_elemento));
vec->elementos[0].str = "This";
vec->elementos[1].str = "is";
vec->elementos[2].str = "a";
vec->elementos[3].str = " test";
vec->elementos[4].str = "string.";
// Sort.
qsort(vec->elementos, vec->tamanho, sizeof(v_elemento), compara);
// Print result.
for (int i = 0; i < 5; ++i) {
printf("%s\n", vec->elementos[i].str);
}
// Clean up.
free(vec->elementos);
free(vec);
And the output result is:
test
This
a
is
string.
Note that there is a space in the string ranked first. :-)
Upvotes: 0