Reputation: 11
I can't figure out how to use qsort. I want to sort an array of strings. Like so:
John Adam
Adam -> John
Stacy Stacy
However, nothing I do seems to work. I've tried copying exactly what others have used (about 5 different qsort functions from various sources) and nothing has worked. I have one for int's that works (backwards but at least it works).
Here's the necessary code I have:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char name[80];
int age;
} RECORD;
RECORD record[25];
int main (int argc, char *argv[80]){ // Using command line to get my strings
int i = 2, j;
for(j = 0; j < (argc / 2); j++) //Converting and storing my ages
{
record[j].age = atoi(argv[i]);
i = i + 2;
}
int p, q = 1;
for(p = 0; p < (argc / 2); p++)
{
strcpy(record[p].name, argv[q]);
q = q + 2;
}
}
int compareByName(const void* a, const void* b) //The qsort that doesn't work at all
{
const char *ia = (const char *)a;
const char *ib = (const char *)b;
return strncmp(ia, ib, 25);
}
int compareByAge (const void * a, const void * b) //My other qsort that works backwards
{
RECORD *RECORDA = (RECORD *)a;
RECORD *RECORDB = (RECORD *)b;
return ( RECORDB->age - RECORDA->age );
}
void printRecords(RECORD r[], int num){
//printing stuff here
double size = sizeof r[0];
double count = sizeof(r)/size; //My qsort with size stuff, doesn't work
qsort(r, count, size, compareByName); // if I do it the same as the other
qsort (r, 25, sizeof(RECORD), compareByAge); //My other qsort that works backwards
//more printing stuff here
}
Upvotes: 1
Views: 1032
Reputation: 10064
First off (this is why your strings aren't sorting), double count = sizeof(r)/size;
is wrong. sizeof(r) isn't doing what you expect it to. You'll need to pass the size of the array to printRecords() as described in this question:
How to get the length of array in C? is "sizeof" is one of the solution?
Second off,
int compareByAge (const void * a, const void * b) //My other qsort that works backwards
is backwards because you're doing it backwards. Comparator functions always return A - B, not B - A.
Upvotes: 1
Reputation: 36504
Okay, I see several issues here.
It's worth noting that sizeof
is evaluated at compile time, so you can't use sizeof(r)
to determine the size of a dynamically-sized array you were passed. I'm going to guess that's why num
is passed in to printRecords
.
As @Chris points out, you're sorting RECORD
structures rather than character pointers, so the comparison function and the qsort
call both need to take that into account.
You have the subtraction reversed in the age comparison - it needs to return a negative number if the left side is less than the right side, so use RECORDA->age - RECORDB->age
.
Upvotes: 1
Reputation: 126253
You don't have an array of strings, you have an array of RECORD
s, and it sounds like you want to sort that array based on the strings in the name
array of the records. So you want something like:
int compareByName(const void *a_, const void *b_) {
RECORD *a = a_, *b = b_;
return strcmp(a->name, b->name);
}
and then you sort with
qsort (r, 25, sizeof(RECORD), compareByName);
Upvotes: 4